编译器是否可以跳过对逗号运算符左操作数的评估?

Mas*_*Man 4 c++ comma

编译器优化有时可以跳过对没有任何后果的某些语句的评估.但是,这也适用于逗号运算符吗?

以下代码在ideone上运行时没有任何错误,但我预计它会崩溃.

#include <iostream>

int main() {
    int x = (1/0, 2);
    std::cout << x << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

如果我将语句更改为,程序会崩溃 int x = 1/0;

Alo*_*ave 8

编译器优化使用As-if规则.

as-if规则

允许任何和所有代码转换不会改变程序的可观察行为

是的,编译器可以对此进行优化.检查以下修改过的样本:

#include <iostream>

int main() 
{
    int y = 1;
    int x = (y=1/0, 2);
    std::cout << x << std::endl;
    //std::cout << y << std::endl;
} 
Run Code Online (Sandbox Code Playgroud)

注释最后一行会在取消注释时正确编译并执行此代码,从而为您提供预期的未定义行为.

正如@jogojapan正确指出的那样,
重要的是要注意标准不保证编译器优化,并且除以零是未定义的行为.所以这段代码确实有一个未定义的行为.可观察行为是由于编译器优化除以零还是由于未定义的行为,我们永远无法知道.从技术上讲,它是未定义的行为.

  • @AlokSave:不是从不使用子表达式,它也必须考虑表达式的副作用.这显然有一个可观察到的副作用.我只能假设除零是未定义的行为,因此编译器可以_assume_(在这种情况下不正确)没有有效的副作用,并且_then_ as-if规则可以应用.(对局部变量的赋值不算作副作用.) (3认同)
  • 讨论未定义的行为是否可观察是徒劳的......顺便说一下之前已经讨论过类似的问题:http://stackoverflow.com/questions/3863656/how-to-cause-an-intentional-division-by-零 (3认同)
  • @MooingDuck:`int main(){int a = 1/0;}`仍然是未定义的行为.因此,对于讨论的情况,编译器是否可以或可以优化它是好的,但讨论本身并不成立,因为从技术上讲,它是UB所有相同的. (3认同)
  • 我认为这不容易.什么是"*可观察行为*"?如果它评估"1/0",那么你将"观察"**不同的**行为.手段,程序的行为根据优化决策而不同. (2认同)
  • @Nawaz:这里的关键是编译器必须保留所有**定义的**行为."1/0"的行为是(明确地)**未定义**,因此编译器可能会也可能不会触发异常. (2认同)