I read somewhere that the ?:
operator in C is slightly different in C++, that there's some source code that works differently in both languages. Unfortunately, I can't find the text anywhere. Does anyone know what this difference is?
views:
888answers:
4Hi
There is a subtle difference in the way in which the expression containing a conditional (or ternary operator) is parsed.
Please check the 'Notes' section on the page http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Comparison_operators
cheers
The principal practical difference is that in C, evaluation of ?: can never result in a l-value where as in C++ it can.
There are other differences in its definition which have few practical consequences. In C++ the first operand is converted to a bool, in C it is compared against 0. This is analagous to the difference in definition of ==, !=, etc. between C and C++.
There are also more complex rules in C++ for deducing the type of a ?: expression based on the types of the 2nd and 3rd operands. This reflects the possibility of user-defined implicit conversions in C++.
Example code. Valid C++; invalid C.
extern int h(int p, int q);
int g(int x)
{
int a = 3, b = 5;
(x ? a : b) = 7;
return h( a, b );
}
gcc
generates the error: "error: invalid lvalue in assignment" when compiling as C, but the code compiles without error when compiling as C++.
Edit: Although ?: can't return an l-value in C, perhaps surprisingly the grammar for ?: is:
conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
This means that a ? b : c = d
parses as (a ? b : c) = d
even though (due to the 'not an l-value' rule) this can't result in a valid expression.
C++ changes the grammar to this:
conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression
While the extension to allow conditional-expression to be an l-value in some situations would have made a ? b : c = d
valid without the grammar change, the new grammar change means that the expression is now valid but with the different meaning of a ? b : (c = d)
.
Although I don't have any evidence for it, my supposition that as the grammar change couldn't break compatibility with existing C code, it was more likely that the new grammar would produce fewer surprises with expressions such as:
make_zero ? z = 0 : z = 1;
The conditional operator in C++ can return an lvalue, whereas C does not allow for similar functionality. Hence, the following is legal in C++:
(true ? a : b) = 1;
To replicate this in C, you would have to resort to if/else, or deal with references directly:
*(true ? &a : &b) = 1;
There is also a subtle difference in the order of operations, such that:
(true ? a = 1 : b = 2);
is valid C++ code, but will throw an error in C without parentheses around the last expression:
(true ? a = 1 : (b = 2));