I thought that the ternary operator returns either a value on the left side or the right side of :
depending on the condition. Why does this following piece of code print 1?
#include <std开发者_如何学编程io.h>
int main(int argc, char const *argv[]) {
int c = 0;
(c?c:0)++;
printf("%i", c);
return 0;
}
You would appear to have a compiler bug, or perhaps a language extension, since this is not valid C. You need an lvalue in order to apply the ++
operator, and (c?c:0)
is not an lvalue.
I've just run across some oddness related to this, too. It seems that the result of a ternary conditional can be treated as an lvalue in gcc 3.3.2, but not in gcc 4.6 (I haven't got more versions ready to hand to narrow it down further). In fact it's not possible to compile gcc 3.3.2 using gcc 4.6 precisely because gcc 4.6 is much pickier about what constitutes an lvalue.
Another example from the gcc 3.3.2 source that doesn't compile with gcc 4.6:
char *x = ...;
*((void**)x)++ = ...;
gcc 4.6 could treat the result of a cast as an lvalue and increment it, but gcc 4.6 will not.
I also don't have the relevant standards to hand to find out of this is something that changed in the official standard or just something that gcc allowed at some stage.
Note also that C++ allows the ternary operator to return an lvalue, though you still can't increment 0. So this is valid C++ but not valid C:
int c = 0, d = 0;
(c?c:d)++;
Simply because you are doing
(c?c:0)++;
If you don't let "++" happen, you will get what you want.
#include <stdio.h>
int main(int argc, char const *argv[]) {
int c = 0;
/* (c?c:0)++; */
printf("%i \n", (c?c:0)++ );
return 0;
}
output is:
$ gcc -o ternary ternary.c
$ ./ternary
0
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
精彩评论