5

考虑以下代码:

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 标准的有效代码?我以前从未见过类似的东西。

4

3 回答 3

8

C11 标准中的脚注 110:

条件表达式不会产生左值。

和 6.5.16 第 2 段:

赋值运算符应具有可修改的左值作为其左操作数。

所以不,该代码不符合 C 标准。

在 C++11 中,它有效的:

如果第二个和第三个操作数是左值并且具有相同的类型,则结果是该类型并且是左值。

因此,这是 C 和 C++ 显着不同的另一个尘土飞扬的角落。如果您的编译器没有产生错误,那么我猜您正在使用具有“C 模式”的 C++ 编译器,而不是正确的 C 编译器;微软?

于 2012-04-05T15:27:34.787 回答
4

This is not legal C, and a compiler that accepts it is wrong. However, you can do the same thing with:

*((i & 1) ? &k : &m) = 99 - i;

and it becomes legal C.

于 2012-04-05T16:23:17.850 回答
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;
于 2012-04-05T15:25:11.257 回答