有一段c++代码如下所示:
class Metadata : public MetaspaceObj {
void print_value_on_maybe_null(outputStream* st) const {
if (this == NULL)
st->print("NULL");
else
print_value_on(tty);
}
}
我只是想知道 C++ 对象中的“this”怎么可能为 NULL。有可能吗?
上面的代码摘自jdk8/openjdk/hotspot/src/share/vm/oops/metadata.hpp。
在 C++ 中,您实际上可以在
NULL
指针上取消引用和调用成员函数。
考虑:
Metadata* pointer = nullptr;
pointer->print_value_on_maybe_null(...);
上面的代码是有效的 C++ 代码,可以正常编译。这样做的问题是它会导致未定义的行为。
回到问题中的代码,我认为过去某个时候,某个地方存在一个错误,导致在空指针上调用成员函数,而不是尝试查找并修复问题的根本原因问题,作者刚刚添加了对
this == NULL
的检查。
从技术上来说,不允许在空指针上调用方法;像这样的事情是未定义的行为:
Metadata * foo = NULL;
foo->print_value_on_maybe_null(NULL);
因此,在这种情况下,编译器可以做任何它想做的事。
但只要该方法不是虚拟的,典型的编译器就不会费心去包含任何检查
foo
是否非空,因为不需要这样的检查。 (当然,对于虚拟方法,它必须检查 foo
来检索 vtable 并调用该方法的适当版本。) 所以。 。 。是的,这是很有可能的,但前提是调用代码有错误(或者许多程序员认为是错误)。
在 NULL 实例上调用方法是未定义的行为。
也就是说,如果您编写以下内容,大多数编译器不会做任何奇怪的事情:
Metadata *x = NULL;
x->print_value_on_maybe_null(&os);
但你走得有点微妙。