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.

3 thoughts on “GCC binary conditional

  1. 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.

  2. I would call them operands, not parameters. Microsoft’s C# language also has this feature, but the operator is a double question mark: ??

    1. 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.

Leave a comment