Contents

GNU's twist on ternary operator

Contents

I was recently browsing the kernel code in attempts to understand some of the weird kernel errors I see in dmesg on one of my machines.

I was a bit surprised to see an interesting syntax I have never seen before. In the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
			    void *data, size_t size, bool conn_ack)
{
    ...
	/*
	 * Don't ACK connection change if there was an error.
	 */
	ret = ucsi_acknowledge(ucsi, err ? false : conn_ack);
	if (ret)
		return ret;

	return err ?: UCSI_CCI_LENGTH(*cci);
}

(Excerpt from ucsi usb code)

What’s up with ?:? Looks like a ternary operator with one of the values omitted. I’ve never seen this syntax before and was a bit confused. Turns out this is a GNU extension.

1
2
3
4
5
int i = 123;
int j = 0;

int x = i ?: 1000;
int y = j ?: 1000;

In the example above, x will have the value of i(123), since its value is non-zero. On the other hand, y will be assigned the value of 1000.

Of course, this is a non-portable code which relies strictly on GNU extensions.