为什么多个递减运算符在C++中工作时不能在C中工​​作?

MD *_* XF 48 c c++ operators decrement

看看这个问题并尝试一些代码:

int x = 100;

while ( 0 <-------------------- x )
{
    printf("%d ", x);
}
Run Code Online (Sandbox Code Playgroud)

我试图编译gcc并得到以下错误:

file.c: In function 'main':
file:c:10:27: error: lvalue required as decrement operand
 while ( 0 <-------------------- x )
Run Code Online (Sandbox Code Playgroud)

但编译与g++作品.为什么这段代码在C++中有效但在C中无效?

小智 91

在C中,--x是一个值,而不是左值.它的作用是递减x,并评估新指定的值x.由于--x不是左值,因此不能减少.

在C++中,--x是左值,而不是右值.它的作用是递减x,并评估x为左值.由于--x再次是左值,它可以再次递减.

--x在C++中成为左值有意义的原因是因为C++引入了引用类型.特定

void f(int &);
int i;
Run Code Online (Sandbox Code Playgroud)

调用可能是有意义的f(--i),i在递减之后通过引用传递.

由于C没有引用类型,因此--i成为左值没什么意义.从历史上看,它从未如此,与C++不同,C从未获得改变规则的令人信服的理由.

请注意,C++需要更广泛的更改,而不是让--x左值实际让它工作.在--x没有任何其他情况下制作左值会产生--x未定义的行为,因为在修改x和后续左值到值转换之间不存在序列点.更清楚如此----x.C++必须修改排序规则才能使其正常工作.在C中,对排序规则的修改可能会导致现有编译器符合新规则的问题,因此除非有很大的好处,否则这些修改可能会被拒绝.

  • 你仍然可以想说'f(& - x)`之类的东西.我不确定我是否在C中找到了"没有意义"的理由. (8认同)
  • 如果你真的想在C中做`f(& - x)`,你可以做`f(( - x,&x))`. (8认同)
  • "---- x"的行为在C++ 11中发生了变化(之后定义良好,之前未定义) (7认同)
  • 我不确定这里的历史背景,但IMO最令人信服的情况是使赋值返回一个左值是对于用户定义的类,你真的不想返回副本.然后其他一切都只是一致性. (5认同)
  • @KerrekSB公平点,但仍然没什么意义.我会说`f(& - x)`不太可能是某人真正想写的东西而不是`f( - x)`.无论如何,C还有一个问题,即规则的变化对于现有的实现会有问题,我补充说. (4认同)