采用以下示例:
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?
答案 0 :(得分:2)
调用函数中的每个评估(包括其他函数调用)都没有特别说明 在执行被调用函数体之前或之后对序列进行测序是不确定的 关于被调用函数的执行。
([intro.execution] / 15)
因此,在g_X + func()
或func() + g_X
形式的表达式中,+
运算符确实没有引入任何排序约束,但仍然可以访问g_X
main
内func()
内的任何一个发生在a
的主体之前或之后,你无法预测哪个。这意味着已定义行为,但b
是1还是2是不可预测的。同样,if (isset($_POST['cookieGiftBox']) && (!isset($POST['sugar']) || ...)
是1还是2是不可预测的。
答案 1 :(得分:2)
乍一看,这看起来像一个未定义的行为,因为引用§1.9/ 15:
如果对标量有副作用 对于相同标量对象的另一个副作用或值计算,对象未被排序 使用相同标量对象的值,行为未定义。
你的例子似乎满足了这些条件:
func
增量g_X
)。g_X
)的值进行计算。另一方面,正如Brian的回答所指出的,函数调用确实引入了排序,尽管不确定。根据这个论点,这不是一个未定义的行为,而只是未指明。