所以我们知道标准并不强制指针大小相等。(这里和这里)(而不是谈论函数指针)
我想知道这实际上如何成为一个问题。我们知道它void *
可以容纳任何东西,所以如果指针大小不同,那将是最大的大小。鉴于此,将 a 分配void **
给 achar **
意味着麻烦。
我的问题是假设void *
并char *
具有相同的大小会有多危险?实际上是否存在不正确的架构?
另外,16位的dos不是我想听到的!;)
void *
并char *
保证具有相同的大小。
void **
不保证具有相同的大小char **
(但在您的实现中非常相似)。
(C99,6.2.5p27)“指向 void 的指针应具有与指向字符类型的指针相同的表示和对齐要求 [...] 指向其他类型的指针不需要具有相同的表示或对齐要求。”
只要不违反对齐要求,就允许将不同对象类型的指针相互分配:分配将涉及(隐式)类型转换,因此与将 a 分配float
给 an一样(不)有问题int
- 它在大多数情况下都有效但在不可能进行有意义的转换时允许爆炸。
char *
并且void *
每个规范都有兼容的对齐要求,因此将 a 分配char **
给void **
变量(反之亦然)永远不会有问题。它们甚至具有兼容的表示,这意味着原则上,char *
通过类型的表达式访问 a void *
- 例如通过取消引用void **
实际指向 a 的 a char *
- 在大多数情况下将按预期工作。当然,反过来(void *
通过取消引用 a 来访问 a char **
)也适用。
例如,期望 a和传入任意指针类型的p
转换说明符是未定义的行为。然而,在 的情况下,只要实现符合 C 标准,它甚至可以在奇异的体系结构(例如,具有不同的指针表示)上工作。printf()
void *
char *
可能出现问题的地方是别名分析:由于有效的类型规则,avoid **
和 achar **
不能别名,如果程序员违背了这个承诺,可能会发生奇怪的事情。人们应该意识到,由于有效的类型(也就是严格的别名),C实际上是强类型的——类型系统非常不健全(即不能保护你不违反它的不变量)......