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