c++ - 赋值中的表达式评估

标签 c++

我很惊讶地看到在 GCC (4.3.2) 上,赋值表达式的左侧可能会在右侧被评估:

int x,y;

int& getX()
{
  std::cout << "getX\n";
  return x;
}

int& getY()
{
  std::cout << "getY\n";
  return y;
}

void test()
{
  x = 3; y= 4;
  getX() = getY();
}

调用 test() 输出

getX
getY

而在 MSVC 上,使用相反的顺序。标准对此有定义吗?

最佳答案

是也不是。

本质上,标准定义它是未指定的,只保证调用函数时参数准备就绪。

编辑:更糟糕的是,表达式求值可能会交错。请参阅示例。

基本上你应该只记得当你有一个函数时,a = b 是一个函数调用:operator=(a , b),然后在函数的参数被评估是未指定的。

GCC 通常从右到左,但优化器可以决定有时从左到右更快。它甚至可以在运行时更改,尽管出于实际原因我从未见过这样的实现。

编辑:

由于标准不 promise 特定的顺序甚至原子执行,因此以下声明:

test(foo() + bar(), fud());

可以导致以下 4 个调用序列:

  • foo, bar, fud
  • 吧,富,富
  • fud, foo, bar
  • fud, bar, foo

当您理解“未指定”术语及其后果时,这些或多或少是“预期的”......但它也可能导致以下 2 个序列:

  • foo, fud, bar
  • 酒吧、酒吧、酒吧

这更令人惊讶。这就是交织。

我在这里省略了+操作,它只能在计算完foobar后执行,但可以执行在 fud 之前或之后。

如果函数是纯函数,或者具有完全不相交的操作集,则应该无关紧要。有时会有一些令人惊讶的副作用,甚至可能导致内存泄漏......

关于c++ - 赋值中的表达式评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8401425/

相关文章:

c++ - 使用 seekg 和 seekp 得到错误的输出

c++ - 如何从静态分配的对象中调用虚函数?

c++ - Qt在特定时间运行?

c++ - 在编译时找到最大公约数

c++ - 如何在 eclipse ".pro File Editor"中打开

c++ - 在 OpenCV 中结合仿射变换的内置函数?

android - 在 Android Studio 中使用共享库时出现 UnsatisfiedLinkError

c++ - 在 libc++ 的 istringstream 的析构函数中未定义对运算符 delete 的引用

c++ - 如何避免在 Windows 和 Linux 中使用不同名称的目标进行重建?

c++ - pgm 二进制文件操作中的图像失真