是给定代码中未定义的行为
Is undefined behavior in given code?
如果p的值为在调用之前初始化为5?请注意,第一个参数是通过引用传递,而第二个参数通过值传递。
int f (int &x, int c) { c = c - 1; if (c==0) return 1; x = x + 1; return f(x,c) * x; }
选项包括:
- 3024
- 6561
- 55440
- 161051
我试着解释:
在这段代码中,将有四个参数为(6,4(、(7,3(、(8,2(和(9,1(的递归调用。最后一个调用返回1。但由于通过引用,以前所有函数中的x现在都是9。因此,f(p,p(返回的值将是9*9*9*1=6561。
这道题来自竞争性考试GATE(见Q.no.42(。答案由GATE给出"全部打分"(意味着没有正确的选项。(密钥集-C,Q.no.42。某处解释为:
在GATE 2013中,由于C/C++中的相同代码会产生未定义的行为,因此对所有代码都进行了标记。这是因为*
不是C/C++中的序列点。正确的代码必须替换
return f(x,c) * x;
带有
res = f(x,c);
return res * x;
但是给定的代码运行良好。GATE的钥匙错了吗?还是这个问题真的错了?
return f(x,c) * x;
此操作的结果取决于评估这两件事的顺序。由于无法预测它们的评估顺序,因此无法预测此操作的结果。
C++03第5章:
除非另有说明,否则单个运算符的操作数和单个运算符的子表达式的求值顺序表达式,以及副作用发生的顺序,都没有具体说明。
因此,在f(x,c) * x
的情况下,操作数的求值顺序是未指定的,这意味着您不知道左操作数还是右操作数将首先求值。
您的代码有未指定的行为,这意味着它将以只有编译器才知道的特定定义方式进行行为。程序员不知道代码会做什么,只知道它会先计算左操作数,或者先计算右操作数。编译器甚至可以根据具体情况更改评估顺序,以达到优化目的。
如果评估顺序很重要,则需要重写代码。依赖于未指定行为的代码总是一个bug,可能是一个非常微妙的bug,不会立即出现。
未指定的行为不同于未定义的行为,这意味着任何事情都可能发生,包括程序失控或崩溃。
- 未定义的引用 .. 使用 OpenCV 编译 C++ 代码时,从命令行
- 为什么我的C++代码无法编译,出现未定义的引用错误
- clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用) - 体系结构的未定义符号 x86_64:
- 我的代码中C++未定义的引用错误?
- 是 VS 代码 MinGW 与 Win32 中未定义的错误
- 如何修复初学者C++代码中发生的未定义行为
- Android NDK.Build命令失败.未定义的引用.clang++:错误:链接器命令失败,退出代码为1
- 使用 Android NDK 使用 clang++ 编译C++代码时对"_Unwind_Resume"的未定义引用
- 我可以在将项目编译为静态库(未定义的引用)时在代码中使用 QImage 吗?
- 如果用户尝试从 JS 调用对象的未定义函数C++则回调C++代码
- 代码::具有 SFML 2,4 的块中未定义的引用
- 在 C++ 中调用时对内联程序集代码的未定义引用
- C++:为什么这段代码给我内存问题/未定义的行为?
- 在另一台计算机中运行 GTKMM 代码时未定义的符号
- 未定义的行为确实有助于现代编译器优化生成的代码
- 为什么当我尝试编译时,我的 c++ 代码不断返回对我的一个构造函数的"未定义的引用"?
- 使用 gcc 编译和使用 clang 编译代码时未定义的引用
- 使用向量(STL)时,未定义的行为,请说明理性背后的以下代码输出
- 当我在Xcode上访问矩阵(openCV垫子)的位置时,为什么我会得到未定义的行为(exc_bad_access(代码=
- 在代码块中的SDL_SHOWSIMPLEMESSAGEBOX中,令人困惑的错误,不确定的引用和未定义的引用