在下面的代码中,我在static_cast<B*>
上使用void*
,它指向A
对象。
A
和B
毫无关系。我了解编译器无法对此提出错误。但是我不明白的是,这在运行时实际上似乎如何工作……?我期望出现段错误或某种错误。
#include <iostream>
using namespace std;
class A {
public:
void f() const {
cout << "f" << endl;
}
};
class B {
public:
void q() {
cout << "q" << endl;
}
};
int main(int argc, char** argv) {
A a;
void* p = &a;
static_cast<B*>(p)->q(); // Prints "q"!
return 0;
}
这背后的机制是什么?
该代码会导致未定义的行为(因为它取消引用未指向B *
对象的B
),这意味着可能发生任何事情。您不应期望任何特定的后果。
要了解您的编译器做了什么,您可以检查程序集。我的猜测是,编译器生成的程序集如果在那里存在B
对象将是正确的:使用隐式参数B::q()
调用函数p
。
为什么这在运行时实际上似乎起作用...?
因为该程序的行为是不确定的。
我期望出现段错误或某种错误。
当行为未定义时,不能保证会出现段错误或某种错误。期望这样做通常是不合理的。当行为未定义时,就没有任何保证。