编译为C++而不是C(错误:左值作为一元'和'操作数)

csh*_*shu 5 c c++ compiler-errors rvalue lvalue

当我使用C++时,这行编译,但不是C:

gmtime(&(*(time_t *)alloca(sizeof(time_t)) = time(NULL))); //make an lvalue with alloca

我对这种差异感到惊讶.甚至没有C++的警告.

当我指定时gcc -x c,消息是:

playground.cpp:25:8: error: lvalue required as unary '&' operand
 gmtime(&(*(time_t *)alloca(sizeof(time_t)) = time(NULL)));
        ^
Run Code Online (Sandbox Code Playgroud)

这不是&一个地址的运营商吗?为什么它在C和C++中有所不同?

虽然我可以在C中使用复合文字,但仍然可以修改我的语法以使其在C&C++中都有效吗?

M.M*_*M.M 8

在C11 6.5.16/3中:

赋值运算符将值存储在左操作数指定的对象中.赋值表达式在赋值后具有左操作数的值,但不是左值.

在C++ 14 5.17/1中:

赋值运算符(=)和复合赋值运算符都是从右到左分组.所有都需要一个可修改的左值作为左操作数,并返回一个左值操作数的左值.

(早期版本的语言标准在每种情况下指定相同的东西).

由于address-of运算符只能在左值上运行,因此代码在C++中是正确的,但在C中则不正确.


关于"是否可以修改我的语法以使其在C&C++中都能正常工作?"的问题.这不是一个理想的目标; 这两种语言是不同的,你应该决定你写的是什么.这与尝试坚持在C和Java中都有效的语法一样有意义.

正如其他人所建议的,你可以写:

time_t t = time(NULL);
gmtime(&t);
Run Code Online (Sandbox Code Playgroud)

这比以前的原始代码有好处:

  • 更简单,因此更容易理解和维护
  • 不依赖于非标准alloca功能
  • 没有潜在的对齐违规
  • 不再使用内存,也许使用更少