有指向不同types的指针有不同大小的平台吗?
C标准允许指向不同types的指针具有不同的大小,例如sizeof(char*) != sizeof(int*)
是允许的。 但是,它要求如果一个指针被转换为一个void*
然后转换回原来的types,它必须与原始值相等。 因此,从逻辑sizeof(void*) >= sizeof(T*)
,所有typesT
sizeof(void*) >= sizeof(T*)
是正确的?
在当今使用的大多数通用平台(x86,PPC,ARM和64位变体等)中,所有指针的大小等于本地寄存器大小(4或8字节),而不pipe指向的types如何。 是否有任何深奥或embedded式平台指向不同types的指针可能有不同的大小? 我具体询问数据指针,虽然我也有兴趣知道是否有平台的function指针具有不寻常的大小。
我绝对不是在问C ++的指针成员和指向成员函数。 这些在普通平台上采用不寻常的大小,甚至可以在一个平台内变化,取决于指针类(非多态,单inheritance,多inheritance,虚inheritance或不完全types)的属性。
从C常见问题回答 :
Prime 50系列使用段07777,空指针偏移0,至lessPL / I。 后来的模型在C中使用了段0,偏移0作为空指针,这就需要新的指令,例如TCNP(Test C Null Pointer),这显然是所有现存编写不当的C代码的错误。 较老的,字寻址的Prime机器也要求比字指针(int *)更大的字节指针(char *)。
Data General的Eclipse MV系列有三种体系结构支持的指针格式(字,字节和位指针),其中两种由C编译器使用:char *和void *的字节指针,以及其他所有的字指针。 由于历史原因,在16位Nova行的32位MV行发展期间,字指针和字节指针在字的不同位置具有偏移,间接和环保护位。 将不匹配的指针格式传递给函数会导致保护错误。 最终,MV C编译器添加了许多兼容性选项来尝试处理具有指针types不匹配错误的代码。
一些霍尼韦尔 – 布尔(Honeywell-Bull)主机对(内部)空指针使用位模式06000。
CDC Cyber 180系列具有48位指针,由指环,段和偏移量组成。 大多数用户(在环11中)具有0xB00000000000的空指针。 在旧的CDC补码机上,通常使用全位字作为各种数据的特殊标志,包括无效地址。
旧的HP 3000系列对字节地址使用不同的寻址scheme,而不是字地址; 像上面的几个机器一样,因此对char *和void *指针使用不同的表示,而不是其他的指针。
符号体系结构Lisp Machine甚至没有传统的数字指针; 它使用一对(基本上不存在的句柄)作为C空指针。
根据使用的“内存模式”,8086系列处理器(PC兼容机)可能使用16位数据指针和32位函数指针,反之亦然。
一些64位Cray机器在一个字的低48位表示int * char *另外使用一些高16位来指示一个字内的字节地址。
其他链接: 来自Chris Torek的关于这些机器的更多细节的消息 。
不是你想问什么,但回到16位的DOS / Windows时代,你确实有一个指针和一个远指针的区别,后者是32位。
我可能有语法错误…
int *pInt = malloc(sizeof(int)); int far *fpInt = _fmalloc(sizeof(int)); printf("pInt: %d, fpInt: %d\n", sizeof(pInt), sizeof(fpInt));
输出:
pInt:2,fpInt 4
因此,从逻辑sizeof(void*) >= sizeof(T*)
,所有typesT的sizeof(void*) >= sizeof(T*)
是正确的?
这并不一定遵循,因为sizeof是关于存储表示的,并不是所有的位模式都必须是有效的值。 我认为你可以写一个符合的实现,其中sizeof(int*) == 8
, sizeof(void*) == 4
,但是int *不超过2 ^ 32个可能的值。 不知道为什么你想要。
回到DOS,8088和分段内存的黄金年代,通常指定一个“内存模型”,其中例如所有代码都适合64k(一个段),但是数据可以跨越多个段; 这意味着一个函数指针将是2个字节,一个数据指针,4个字节。 不知道是否有人仍然在编程这种机器,也许有些人仍然在embedded式应用中生存。
人们可以很容易想象一个哈佛架构机器具有不同大小的函数指针和所有其他指针。 不知道一个例子…
近点和远点指针仍然用于一些带有页面闪存或RAM的embedded式微控制器,以允许您指向同一页面(靠近指针)或另一页面(远的指针,因为它包含页面信息而较大的指针)中的数据。
例如,飞思卡尔的HCS12微控制器采用16位冯诺依曼结构,这意味着没有地址可以超过16位。 由于这个限制,会占用大量的代码空间,所以有一个8位的页面寄存器。
因此,要指向同一代码页中的数据,只需指定16位地址; 这是一个接近的指针。
要指向另一个代码页中的数据,必须在该页面中包含8位页码和16位地址,从而产生一个24位远指针。
例如,指向数据的指针的大小可能与指向函数的指针的大小不同。 在embedded式系统的微处理器中发生这种情况是很常见的。 所提到的像dmckee这样的哈佛架构机器很容易发生。
事实certificate,这使得海湾合作委员会后端痛苦发展! 🙂
编辑:我不能进入我正在谈论的具体机器的细节,但让我补充为什么哈佛机器使这容易发生。 哈佛架构对指令和数据有不同的存储和path,因此,如果指令的总线比数据的“总线”大,那么你肯定会有一个函数指针,它的大小要大于指向数据的指针!