Archive for May 2008
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|
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.