gcc:在同一指令上使用相同的var时引用参数更改

时间:2012-11-29 12:31:40

标签: c++ gcc

我指出了一个奇怪的gcc行为: 当在同一指令上使用相同的变量时,并且当通过一个函数调用(通过引用或指针传递的变量)修改此变量时,不会修改同一指令的其他函数的变量更改。

这是正常的c ++行为还是boggus? 注意:未设置优化(-O)标志 注2:这与solaris CC编译器配合使用。

使用gcc 4.5.3进行演示(在linux或mingw / cygwin上)

class C {
public:
  const C & inc(int & i) const       
  {
     ++i;
     cout << "inc: i = " << i << endl; return *this;
  }
  const C & see(int i) const   
  {     
     cout << "see: i = " << i << endl; return *this; 
  }
  const C & see2(const int & i) const {  
    cout << "see2: i = " << i << endl; return *this; }
  };

int main()
{
  C c;
  int i = 0;
  c.see(i).inc(i).see(i).see2(i).inc(i).see(i).see2(i);
  c.see(i);
  return 0;
}

输出:

  

见:i = 0
  inc:i = 1
  见:i = 0 :1预期
  见2:i = 1
  inc:i = 2
  见:i = 0 :2预期
  见2:i = 2
  见:i = 2

2 个答案:

答案 0 :(得分:2)

函数参数的评估顺序相互之间是不确定的。在这种情况下,gcc已选择将i评估为早期传递给see方法调用。

您的代码相当于:

class C {};
C &inc(C &c, int &i) { ++i; return c; }
C &see(C &c, int i) { std::cout << i << '\n'; return c; }
C c;
int i = 0;
see(inc(c, i), i);

see参数的有效评估顺序为:

1. evaluate inc(...) to pass c to see(...)
2. evaluate i as an rvalue to pass to see(...)

1. evaluate i as an rvalue to pass to see(...)
2. evaluate inc(...) to pass c to see(...)

在前一种情况下,程序打印1;在后者中它打印0

请注意,行为未指定未定义;它必须打印01。这是因为序列点在调用inc之前和之后获得;在C ++ 11中,对于调用函数(1.9p15)中的求值,函数的执行是不确定的(但不是未序列的)。

答案 1 :(得分:0)

这是正确的行为:它不是由标准指定的,其中执行给定语句的子表达式。在您的情况下,显然编译器首先执行所有i子表达式,即使i的副本将它们传递给see()之前的之前的不同调用对inc()的调用进行评估。