【发布时间】:2017-02-15 11:06:40
【问题描述】:
假设我们有以下代码:
int i = 1;
int j = i++ + ++i;
我知道这是一个未定义的行为,因为在分号之前,这是一个序列点,i 的值已经改变了不止一次。这意味着即使运算符加号的优先级是从左到右,编译器也可能有两种可能:
案例 1)
- 取
i++的值---i的值为1 - 取
++i的值---i的值为2 - 执行运算符加号并将结果3分配给
j并执行i++的副作用(此步骤的顺序也未定义但我们不在乎,因为它不会改变结果)
案例 2)
- 取
i++的值---i的值为1 - 做
i++的副作用---i的值为2 - 取
++i的值---i的当前值为3 - 执行运算符加号并将结果为 4 分配给
j
如果这里没有问题,我有一个问题:
int j = ++i + i++;
上面的代码仍然是未定义的行为吗?
在我看来,只有一种可能:
- 做
++i的副作用---i的值为2 - 取
i++的值---i的值为2 - 执行运算符加号并将结果4分配给
j并执行i++的副作用(此步骤的顺序也未定义但我们不在乎,因为它不会改变结果)
我说的对吗?
顺便说一句,我已阅读此链接:
Undefined behavior and sequence points
【问题讨论】:
-
评估您的第二个示例有多种方法,就像评估您的第一个示例有多种方法
-
您错过了未定义行为的概念。任何事情都有可能发生。程序可能会崩溃。程序可以输出42...等等等等
-
两者都是UB。而“运算符的优先级”只是如何解析表达式并将括号放在表达式中。
-
例如:live example 为 clang 打印 4,但如果在命令行 you get 5 中将
clang++替换为g++。此外,两者都对 UB 发出警告。 -
您将关联性和优先级与评估顺序混淆了。参数以未指定的顺序进行评估。仅当存在多个二元运算符时,关联性才重要。
标签: c++ undefined-behavior side-effects sequence-points