GCC binary conditional
I recently ran into a nifty GCC extension to the C/C++ language, the binary conditional:
z = x ?: y;
At first glance this looks like the C++ ternary operator:
z = x ? y : w;
But notice that this new operator above is binary — it has only two parameters. Unlike the dash and greater-than symbols in the C arrow operator (pointer -> member), GCC does not require that the binary conditional’s question mark and colon be adjacent, but you should probably write them adjacently to better distinguish them from the ternary operator.
But what does the binary conditional do? In short, it is analagous to the Perl || operator, the Python or operator, and the Ruby || operator. It evaluates to the value on the left unless the value on the left evaluates to false, in which case it evaluates to the value on the right.
x | y | x ?: y |
0 | 0 | 0 |
0 | 80 | 80 |
NULL | 0x16E212B4 | 0x16E212B4 |
15 | 0 | 15 |
15 | 20 | 15 |
0x16E212BC | 0x16E212E8 | 0x16E212BC |
You may wonder why the C || operator can’t be used for this same purpose. The reason for this is that C’s || operator performs a pure logical or operation: it always collapses the result value to 0 or 1. For example, the expression 80 || 0 evaluates to 1, not to 80. However, the expression 80 ?: 0 evaluates to 80.
That’s pretty nifty, although ?: is certainly a bit unfortunate; it’s not obvious from looking at the operator what it should do. Worse, it appears that the binary conditional is unique to GCC. I’ve tried this with several other C/C++ compilers without success.
There is, however, a more portable way to accomplish the same thing. Instead of writing x ?: y, you can write the equivalent x ? x : y. This is a little less concise, but it has the advantage that any skilled C programmer can immediately understand what it does. And it is more portable.
Writing x ? x : y instead of x ?: y has the unwanted feature that x is evaluated twice. Thus any side-effects performed in x are repeated and maybe performance could be lost in some cases when the optimizer cannot prove that it can evaluate x only once and use the value twice.
Palec
September 11, 2014 at 8:20 am
I would call them operands, not parameters. Microsoft’s C# language also has this feature, but the operator is a double question mark: ??
Eq
November 22, 2014 at 11:13 pm
Oops, I’m half-asleep. The ?? operator depends on the first operand being null, not false — but it’s the same sort of fall-through concept.
Eq
November 22, 2014 at 11:14 pm