Can size of pointers to non-union classes differ?

折月煮酒 提交于 2019-12-04 05:01:21

C has a hard requirement that all pointers to all structure types have the same representation and alignment.

6.2.5 Types

27 [...] All pointers to structure types shall have the same representation and alignment requirements as each other. [...]

C++ effectively requires binary compatibility with a C implementation, because of the standard's requirements for extern "C", so indirectly, this requires all pointers to structure types that are valid in C (POD types, pretty much) to have the same representation and alignment in C++ too.

No such requirement seems to have been made for non-POD types, so an implementation would be allowed to use different pointer sizes in that case. You suggest that that cannot work, but to follow your example,

struct G { };
struct H : G { };

struct W
{
  virtual G* f() { ... }
};
struct X : W
{
  virtual H* f() { ... }
};

could be translated to (pseudo-code)

struct W
{
  virtual G* f() { ... }
};
struct X : W
{
  override G* f() { ... }
  inline H* __X_f() { return static_cast<H *>(f()); }
};

which would still match the requirements of the language.

A valid reason why two pointers to structure types might not be identical is when a C++ compiler would be ported to a platform that has an existing C compiler with a poorly-designed ABI. G is a POD type, so G * needs to be exactly what it is in C. H is not a POD type, so H * does not need to match any C type.

For alignment, that can actually happen: something that really happened is that the x86-32 ABI on a typical GNU/Linux system requires 64-bit integer types to be 32-bit aligned, even though the processor's preferred alignment is actually 64-bit. Now comes another implementer, and they decide that they do want to require 64-bit alignment, but are stuck if they want to remain compatible with the existing implementation.

For sizes, I cannot think of a reasonable scenario in which it would happen, but I am unsure whether that might be a lack of imagination on my part.

As far as I understand C and C++ assume memory to be linearly byte addressable. Certain platforms (early ARM) however insist on word aligned loads and stores. In such a case, it is the compiler's responsibility to round the pointer to the word boundary and then perform the necessary bit shift operations when fetching say a char.

But since this is all done only on loads and stores, all pointers still all look the same.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!