c ++对ambigous sum表达式的评估

时间:2015-12-09 00:49:59

标签: c++

采用以下示例:

int g_X;
int func() {
 return ++g_X;  // using g_X++ is not an option
}
int main() {
 g_X = 0;
 int a = g_X + func();
 g_X = 0;
 int b = func() + g_X;
 g_X = 0; int temp = g_X;
 int c = temp + func();

 return 0;
}

a和b都是2,c具有期望值1(使用Visual Studio 2010到2015测试)。我读到总和与序列点无关(例如https://en.wikipedia.org/wiki/Sequence_point),因此订单不固定。但我认为在函数调用之前会捕获g_X的值。 我是否真的处于未定义的行为领域或者是否有某种方式不必使用temp var?

2 个答案:

答案 0 :(得分:2)

  

调用函数中的每个评估(包括其他函数调用)都没有特别说明   在执行被调用函数体之前或之后对序列进行测序是不确定的   关于被调用函数的执行。

([intro.execution] / 15)

因此,在g_X + func()func() + g_X形式的表达式中,+运算符确实没有引入任何排序约束,但仍然可以访问g_X mainfunc()内的任何一个发生在a的主体之前或之后,你无法预测哪个。这意味着已定义行为,但b是1还是2是不可预测的。同样,if (isset($_POST['cookieGiftBox']) && (!isset($POST['sugar']) || ...)是1还是2是不可预测的。

答案 1 :(得分:2)

乍一看,这看起来像一个未定义的行为,因为引用§1.9/ 15:

  

如果对标量有副作用   对于相同标量对象的另一个副作用或值计算,对象未被排序   使用相同标量对象的值,行为未定义。

你的例子似乎满足了这些条件:

  1. +运算符的操作数的评估相对于彼此没有排序(但见下文)。
  2. 对标量对象有副作用(func增量g_X)。
  3. 使用相同标量对象(g_X)的值进行计算。
  4. 另一方面,正如Brian的回答所指出的,函数调用确实引入了排序,尽管不确定。根据这个论点,这不是一个未定义的行为,而只是未指明。