考虑以下代码:
int i, k, m;
k = 12;
m = 34;
for (i = 0; i < 2; i++) ((i & 1) ? k : m) = 99 - i;
printf("k: %ld m: %ld\n\n", k, m);
在这个愚蠢的例子中,条件运算符表达式是:
的快捷方式if (i & 1) k = 99 - i; else m = 99 - i;
我的编译器没有抱怨并且执行这段代码会产生预期的输出
k: 98 m: 99
我的问题是,如果这是符合C标准的有效代码吗?我以前从未见过这样的东西。
答案 0 :(得分:8)
C11标准中的脚注110:
条件表达式不会产生左值。
和6.5.16第2段:
赋值运算符应具有可修改的左值作为其左操作数。
所以不,该代码不符合C标准。
在C ++ 11中, 有效:
如果第二个和第三个操作数是左值并且具有相同的类型,则结果是该类型并且是左值。
所以这是另一个尘封的角落,C和C ++显着不同。如果您的编译器没有产生错误,那么我猜你正在使用带有“C模式”的C ++编译器,而不是正确的C编译器; MSVC?
答案 1 :(得分:4)
这不是合法的C,接受它的编译器是错误的。但是,你可以用以下方法做同样的事情:
*((i & 1) ? &k : &m) = 99 - i;
它变成了合法的C.
答案 2 :(得分:1)
在C ++中使用条件作为lval是有效的,但在C中则不行。
在C ++中(ISO?IEC 14882:1998(E)5.16.4)
如果第二个和第三个操作数是左值并且具有相同的类型,则结果是该类型并且是左值。
如果你想在C中使用类似的技巧,你应该使用指针:
ISO / IEC 9899:TC2,6.5.14.6
如果第二个和第三个操作数都是指针,或者一个是空指针常量而另一个是指针,则结果类型是一个指向限定类型的指针,该类型具有两个操作数所指向的类型的所有类型限定符
*((i & 1) ? &k : &m) = 99 - i;