?: ternary conditional operator behaviour when leaving one expression empty
Solution 1
This is a GNU C extension (see ?: wikipedia entry), so for portability you should explicitly state the second operand.
In the 'true' case, it is returning the result of the conditional.
The following statements are almost equivalent:
a = x ?: y;
a = x ? x : y;
The only difference is in the first statement, x
is always evaluated once, whereas in the second, x
will be evaluated twice if it is true. So the only difference is when evaluating x
has side effects.
Either way, I'd consider this a subtle use of the syntax... and if you have any empathy for those maintaining your code, you should explicitly state the operand. :)
On the other hand, it's a nice little trick for a common use case.
Solution 2
This is a GCC extension to the C language. When nothing appears between ?:
, then the value of the comparison is used in the true case.
The middle operand in a conditional expression may be omitted. Then if the first operand is nonzero, its value is the value of the conditional expression.
Therefore, the expression
x ? : y
has the value of x if that is nonzero; otherwise, the value of y.
This example is perfectly equivalent to
x ? x : y
In this simple case, the ability to omit the middle operand is not especially useful. When it becomes useful is when the first operand does, or may (if it is a macro argument), contain a side effect. Then repeating the operand in the middle would perform the side effect twice. Omitting the middle operand uses the value already computed without the undesirable effects of recomputing it.
Related videos on Youtube
TooBored
Updated on August 05, 2020Comments
-
TooBored almost 4 years
I was writing a console application that would try to "guess" a number by trial and error, it worked fine and all but it left me wondering about a certain part that I wrote absentmindedly,
The code is:
#include <stdio.h> #include <stdlib.h> int main() { int x,i,a,cc; for(;;){ scanf("%d",&x); a=50; i=100/a; for(cc=0;;cc++) { if(x<a) { printf("%d was too big\n",a); a=a-((100/(i<<=1))?:1); } else if (x>a) { printf("%d was too small\n",a); a=a+((100/(i<<=1))?:1); } else { printf("%d was the right number\n-----------------%d---------------------\n",a,cc); break; } } } return 0; }
More specifically the part that confused me is
a=a+((100/(i<<=1))?:1); //Code, code a=a-((100/(i<<=1))?:1);
I used
((100/(i<<=1))?:1)
to make sure that if100/(i<<=1)
returned 0 (or false) the whole expression would evaluate to 1((100/(i<<=1))?:***1***)
, and I left the part of the conditional that would work if it was true empty((100/(i<<=1))? _this space_ :1)
, it seems to work correctly but is there any risk in leaving that part of the conditional empty?-
Justin Garrick almost 14 yearsThis type of conditional is called a ternary operation. You might get a better response if you re-tag or re-title your post to include 'ternary'.
-
ULysses almost 14 years<a href="en.wikipedia.org/wiki/%3F:">This</a> link, C Variants section
-
JeremyP almost 14 years@Segphault: it is called the conditional operator (in C). It is an example of a ternary operator which is a generic term meaning any operator with three operands.
-
Lumen almost 14 yearsIf YOU have doubts, which lead to this question, there is no doubt you should have made the true-case assignment explicit. TooBored.... Consider not coding dumb console games, 'cause it's a positive boredom feedbacker.
-
Keith Thompson almost 8 years@JeremyP: Yes, "ternary operator" is a generic term for an operator with three operands. But the "conditional operator" (
?:
) happens to be the only ternary operator in C (and in many similar languages), so it's commonly called "the ternary operator". The usage is perhaps a bit sloppy, but common. (The C standard never refers to?:
as a "ternary" operator. In fact it uses the phrase "ternary operator" only when discussing the semantics of thefma()
function, which computes(x × y) + z
.)
-
-
kennytm almost 14 yearsAlmost equivalent ... except
x
is evaluated only once inx ?: y
. -
Stephen almost 14 years@KennyTM: True, I should explicitly state that.
-
Ted over 8 yearsI tried this ternary syntax with missing second operand on xlc (IBM XL C/C++ for AIX, V11.1) and it also worked.
-
rudimeier over 7 yearsI know some projects which seem to be tested highly portable although using "?:". Any example of a non-working compiler?
-
Lars Nyström over 4 yearsHah, "perfectly equivalent". Of course everything is perfectly equivalent if you ignore the differences...
-
mbauman over 4 yearsIt really is perfectly equivalent in that simple case.
-
4LegsDrivenCat over 2 yearsIt works for Clang too, not only GCC.