【发布时间】:2021-08-10 23:33:09
【问题描述】:
我很困惑为什么这会导致未定义的行为。让我先复制粘贴教科书上的解释,然后展示我自己完美运行的代码和程序。
Precedence 指定操作数的分组方式。它什么也没说 关于计算操作数的顺序。在大多数情况下, 该顺序在很大程度上未指定。在以下表达式中*
int i = f1() * f2();:
*我们知道必须先调用f1和f2才能进行乘法运算。毕竟是他们的 结果相乘。然而,我们无从得知 f1 是否会在 f2 之前被调用,反之亦然。对于运营商 不指定评估顺序,表达式会出错 引用和更改同一个对象。这样做的表达式有 未定义的行为(第 2.1.2 节,第 36 页)。举个简单的例子,-- C++ 入门 - Stanley B. Lippman 第 193 页
所以,我尝试通过编写自己的代码来应用它,但我从来没有得到未定义的行为?谁能解释一下这是什么意思?
#include <iostream>
using std::cout;
using std::endl;
int f1() { return (5 + 5 * 4 / 2 - 3); } // 12
int f2() { return (10 + 2 * 10 / 2 - 5); } // 15
int main()
{
int i = f1() * f2();
cout << i << endl;
return 0;
}
【问题讨论】:
-
您的两个函数都不会修改同一个变量,因此它们的求值顺序无关紧要。
-
it is an error for an expression to refer to and change the same object好吧,f1和f2都不会改变同一个对象。 -
第一:您希望如何检测未定义的行为?也就是说,如果您遇到未定义的行为,您希望看到的输出或程序行为会向您表明这一点吗?第二:为什么您认为您的示例代码会调用未定义的行为?
f1和f2都不会修改i或其他任何与此相关的内容。 -
您可以通过实验验证 UB 的存在,但永远不能absence UB。 (发布的代码是可以的,但你不能仅仅通过运行它来证明)。
-
顺便说一句,李普曼在这里大错特错。 f1() 和 f2() 访问和修改同一个变量不是未定义的行为。未指定顺序,但任一顺序均已明确定义。您可以在 f2() 之后调用 f1() 或在 f1() 之后调用 f2(),但没有别的。
标签: c++ c++11 language-lawyer operator-precedence evaluation