向上转换空指针是否会导致未定义的行为
Does upcasting a null pointer lead to undefined behavior
我想知道以下代码是否会导致未定义的行为:
#include <cstddef>
#include <cstdio>
struct IA {
virtual ~IA() {}
int a = 0;
};
struct IB {
virtual ~IB() {}
int b = 0;
};
struct C: IA, IB {};
int main() {
C* pc = nullptr;
IB* pib = pc;
std::printf("%p %p", (void*)pc, (void*)pib);
}
Stroustrup 在 his 1989 multiple inheritance paper [PDF] 的第 4.5 节中讨论了这种情况:
The solution is to elaborate the conversion (casting) operation to
test for the pointer-value 0 [...]
The added complexity and run-time overhead are a test and an
increment.
实现明确检查空值并确保强制转换的结果仍然是空值。这在 C++98 中是正确的,并且在 C++11 和 nullptr
.
中没有改变
这在多个基数 classes 的情况下尤其重要,其中从派生 class 到其中一个基数 classes 的转换可能需要更改实际值指针。
在您的示例中,C
在内存中的布局将首先包含 IA
的字节,然后是 IB
的字节。转换为 IA
很简单,因为指向 C
开头的指针也将指向 C
的 IA
部分的开头。另一方面,转换为 IB
需要将 C
指针移动 IA
的大小。在 nullptr 情况下执行此移位将导致转换后的非空指针,因此对空值进行特殊处理。
作为,标准中的相关部分是[conv.ptr] §4.10:
A prvalue of type “pointer to cv D
”, where D
is a class type, can be
converted to a prvalue of type “pointer to cv B
”, where B
is a base
class [...] of D
. [...] The result of the conversion is a pointer to
the base class subobject of the derived class object. The null pointer
value is converted to the null pointer value of the destination type.
向上转换空指针明确定义为您提供另一个空指针:
4.10p3:
A prvalue of type "pointer to cv D
", where D
is a class type, can be converted to a prvalue of type "pointer to cv B
", where B
is a base class of D
. ... The null pointer value is converted to the null pointer value of the destination type.
我想知道以下代码是否会导致未定义的行为:
#include <cstddef>
#include <cstdio>
struct IA {
virtual ~IA() {}
int a = 0;
};
struct IB {
virtual ~IB() {}
int b = 0;
};
struct C: IA, IB {};
int main() {
C* pc = nullptr;
IB* pib = pc;
std::printf("%p %p", (void*)pc, (void*)pib);
}
Stroustrup 在 his 1989 multiple inheritance paper [PDF] 的第 4.5 节中讨论了这种情况:
The solution is to elaborate the conversion (casting) operation to test for the pointer-value 0 [...]
The added complexity and run-time overhead are a test and an increment.
实现明确检查空值并确保强制转换的结果仍然是空值。这在 C++98 中是正确的,并且在 C++11 和 nullptr
.
这在多个基数 classes 的情况下尤其重要,其中从派生 class 到其中一个基数 classes 的转换可能需要更改实际值指针。
在您的示例中,C
在内存中的布局将首先包含 IA
的字节,然后是 IB
的字节。转换为 IA
很简单,因为指向 C
开头的指针也将指向 C
的 IA
部分的开头。另一方面,转换为 IB
需要将 C
指针移动 IA
的大小。在 nullptr 情况下执行此移位将导致转换后的非空指针,因此对空值进行特殊处理。
作为
A prvalue of type “pointer to cv
D
”, whereD
is a class type, can be converted to a prvalue of type “pointer to cvB
”, whereB
is a base class [...] ofD
. [...] The result of the conversion is a pointer to the base class subobject of the derived class object. The null pointer value is converted to the null pointer value of the destination type.
向上转换空指针明确定义为您提供另一个空指针:
4.10p3:
A prvalue of type "pointer to cv
D
", whereD
is a class type, can be converted to a prvalue of type "pointer to cvB
", whereB
is a base class ofD
. ... The null pointer value is converted to the null pointer value of the destination type.