繁体   English   中英

向上转换空指针会导致未定义的行为

[英]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);
}

向上转换空指针是明确定义的,以便为您提供另一个空指针:

4.10p3:

类型为“指向cv D指针”的prvalue,其中D是类类型,可以转换为类型“指向cv B指针”的prvalue,其中BD的基类。 ...空指针值将转换为目标类型的空指针值。

Stroustrup在1989年的多重继承文件[PDF]第4.5节中讨论了这个案例:

解决方案是详细说明转换(强制转换)操作以测试指针值0 [...]

增加的复杂性和运行时开销是测试和增量。

该实现显式检查空值,并确保转换的结果仍为空值。 这在C ++ 98中是正确的,并且在C ++ 11和nullptr没有改变。

这在多个基类的情况下尤其重要,其中从派生类到其中一个基类的强制转换可能需要更改指针的实际值。

在您的示例中,内存中C的布局将首先包含IA的字节,然后是IB的字节。 投射到IA是繁琐,作为指针的开头C也将指向开头IA的一部分C 另一方面,转换为IB ,需要将C指针移动IA的大小。 在nullptr情况下执行此移位将导致在强制转换后的非空指针,因此对空值进行特殊处理。

正如aschepler指出的 ,标准中的相关部分是[conv.ptr]§4.10:

类型为“指向cv D指针”的prvalue,其中D是类类型,可以转换为类型“指向cv B指针”的prvalue,其中BD的基类[...]。 [...]转换的结果是指向派生类对象的基类子对象的指针。 空指针值将转换为目标类型的空指针值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM