c – 指向非联合类的指针大小是否不同?

我知道有些硬件平台你需要更多的信息来指向一个char而不是你需要指向一个int(具有不可寻址字节的平台,所以指向char的指针需要存储一个指向一个单词的指针以及一个索引字中的一个字节).因此有可能sizeof(int *)< sizeof(char *)在这样的平台上. 指向非联合类的指针会发生类似的事情吗? C允许在虚函数上使用协变返回类型.假设我们有这样的类:
struct Gadget
{
  // some content
};


struct Widget
{
  virtual Gadget* getGadget();
};

任何调用getGadget()的代码都必须在接收Gadget *时工作,但是当它接收到指向从Gadget派生的类型的指针时,相同的代码(实际上是相同的编译二进制代码)必须工作(可能是一个定义的在一个完全不同的图书馆).我可以合理地看到这种情况发生的唯一方法是所有非联合类类型T和U的sizeof(T *)== sizeof(U *).

所以我的问题是,在一个特定平台上给出一个特定的实用编译器(不包括假设的Hell),是否有理由期望所有指向非联合类类型的指针都具有相同的大小?或者是否有一个实际的原因,为什么编译器可能希望使用不同的大小,同时保持符合协变返回类型?

在存在指针的不同“级别”的平台上(例如__near和__far),假设应用于两者的相同属性.

解决方法

C有一个硬性要求,即所有结构类型的指针都具有相同的表示和对齐.

6.2.5 Types

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

C有效地需要与C实现的二进制兼容性,因为标准对extern“C”的要求,所以间接地,这需要所有指向结构类型的指针,这些结构类型在C(POD类型,相当多)中有效,以具有相同的表示和对齐在C中也是如此.

似乎没有对非POD类型做出这样的要求,因此在这种情况下允许实现使用不同的指针大小.你建议那不行,但要按照你的例子,

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

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

可以翻译成(伪代码)

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

这仍然符合语言的要求.

两个指向结构类型的指针可能不相同的一个正当理由是,当C编译器被移植到具有设计不良的ABI的现有C编译器的平台时. G是POD类型,因此G *必须与C中的完全相同.H不是POD类型,因此H *不需要匹配任何C类型.

对于对齐,这实际上可能发生:真正发生的事情是典型的GNU / Linux系统上的x86-32 ABI需要64位整数类型才能进行32位对齐,即使处理器的首选对齐实际上是64位.现在又出现了另一个实现者,他们认为他们确实需要64位对齐,但如果他们想要与现有实现保持兼容,则会陷入困境.

对于尺寸,我想不出它会发生的合理情况,但我不确定这是否可能是我缺乏想象力.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...