从void **转换为char **有多危险

时间:2012-06-30 16:26:46

标签: c pointers void-pointers

所以我们知道标准不会强制指针大小相等。 (herehere)(而不是讨论函数指针)

我想知道实际上这可能是一个问题。我们知道void *可以容纳任何东西,所以如果指针大小不同,那将是最大的大小。鉴于此,将void **分配给char **意味着麻烦。

我的问题是假设void *char *具有相同的大小是多么危险?实际上是否存在不属实的架构?

另外,16位dos不是我想听到的! ;)

2 个答案:

答案 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实际上是强类型的 - 类型系统只是非常不健全(即不能保护你免受违反其不变量)......