简体   繁体   English

为什么static_cast仍然可以使用空指针尽管切片?

[英]Why does static_cast still work with null pointers in spite of slicing?

If we use multiple inheritance, slicing will make the addresses to parent objects differ from the address to leaf objects: 如果我们使用多重继承,切片将使父对象的地址与地址到叶对象不同:

struct X {int x};
struct Y {int y};
struct Z : X, Y {int z};

So if we have a Z object z , its address &z will not coincide with the address of its Y parent: static_cast<Y*>(&z) is four bytes higher than &z . 因此,如果我们有一个Z对象z ,它的地址&z与其Y父地址重合: static_cast<Y*>(&z)&z高四个字节。

The good thing about static_cast is that it's, well, static, so doesn't take up runtime (compared to dynamic_cast , that is). static_cast的好处在于,它是静态的,因此不会占用运行时(与dynamic_cast相比)。 However, if we have a Z* that points at 0 , every cast to a parent should and does yield a null pointer as well. 但是,如果我们有一个Z*指向0 ,那么每次转换为父对象都应该并且确实产生一个空指针。 Why does this work and how is it implemented? 为什么这样做以及如何实施? Does that imply that every single static_cast introduces a branch instruction? 这是否意味着每个static_cast引入了分支指令?

Yes, both an implicit conversion from a pointer to a derived class to a pointer to a base class and a static_cast back again must preserve null pointer values. 是的,从指向派生类的指针到指向基类的指针和static_cast的隐式转换都必须保留空指针值。 This means that a branch is usually required in the generated code for multiple inheritance cases where the base class address does not coincide with the derived class address. 这意味着在生成的代码中通常需要一个分支用于多个继承情况,其中基类地址与派生类地址不一致。

It's theoretically possible for an implementation to reserve a range of addresses around a 'zero' address to represent null pointers and avoid the branch in this case but it would be at the expense of adding extra checking for comparisons of null pointers. 从理论上讲,实现可以在“零”地址周围保留一系列地址来表示空指针,并避免在这种情况下使用分支,但这会以增加额外检查来进行空指针比较为代价。

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

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