我最近在一次采访中被要求预测以下程序的输出:
#include <bits/stdc++.h>
using namespace std;
class a {
public:
int x = 10;
void f() { cout << "hello" << endl; }
void g() { cout << x << endl; }
};
int main() {
a* ptr = new a();
a* ptr1;
a* ptr2 = NULL;
ptr->f();
ptr1->f();
ptr2->f();
ptr->g();
ptr1->g();
ptr2->g();
}
当使用Null和wild指针调用函数f((时,输出为hello,但当使用这两个指针调用函数g((时在控制台上看不到输出。这种行为的原因可能是什么?
在我看来,唯一有效的答案是:程序调用Undefined Behavior,因此任何结果都是有效的。无法判断任意编译器将生成什么,并且程序整体无效。
此外,请阅读为什么我不应该#include <bits/stdc++.h>
?
在未初始化指针和null指针上调用方法的行为是未定义的。这意味着您不能再以任何有意义的方式对程序的行为进行推理。它可以做任何事情。例如,它可以点披萨。
您的程序有未定义的行为。话虽如此,对于为什么对f
的调用似乎有效,而对g
的调用会导致奇怪的行为,有一个合理的解释。
这些函数在概念上多次被翻译为:
void mangled_function_for_f(a* const this)
{
cout << "hello" << endl;
}
void mangled_function_for_g(a* const this)
{
cout << this->x << endl;
}
请注意,this
未在f
中使用。因此,对f
的调用似乎是可以的,而对g
的调用则不然。
PS不要指望我在每个平台上的解释,甚至在具有不同编译器选项的同一平台上。最好避免使用导致未定义行为的代码。