我读到将指向一个类型的指针指向另一个指向另一个类型的指针是非法的;例如,在本书中:
C如何编程7 ed。 PAG。 299
常见编程错误7.7 将一种类型的指针分配给a 另一种类型的指针,如果两者都不是void *类型的语法 错误。
或此URL:
但是在C11标准中写下了:
指向对象类型的指针可以转换为指向a的指针 不同的对象类型。如果结果指针不正确 对于引用类型对齐,行为未定义。 否则,当再次转换回来时,结果应该相等 到原始指针。
所以我理解,只有存在对齐问题时,行为才会被定义。
事实上,像GCC 4.8或cl 2013这样的编译器只会发出不兼容指针类型的分配警告。
void指针不存在该异常。
所以:
int a = 10;
float b = 100.22f;
int *p_a = &a;
float *p_f = &b;
p_a = p_f; // NOT ILLEGAL but WARNING
p_f = p_a; // converted back again. it still works
void *v_p = p_a; // NOT ILLEGAL NO WARNING
p_a = v_p; // converted back again. it still works
我明白吗?或者我错过了什么?
P.S。 任何人都可以向我展示一个"对齐问题的例子"?
答案 0 :(得分:2)
您可以将指针视为内存中指向数据的偏移量,无论它是什么类型。任何标准指针(不是智能指针)都有固定的大小,具体取决于系统(32位或64位)。因此,您可以将它们分配给其他,现代编译器将警告您有关危险的操作,但问题是当您尝试取消引用无法比较的类型的指针时。解除引用时,app会查找与指向类型对应的字节数,因此在下一个示例中
int b = 10;
int* pB = &b;
double* pA = pB;
在dereference pB上你得到10(int的大小是4个字节),并且在取消引用pA时你会得到垃圾或崩溃,因为接下来的4个字节(double是8个字节)可以是为另一个变量分配的内存空间。
结论:在将指针类型分配给彼此时,请跟踪指针类型,特别是如果使用void *作为中介间接指定它们。 指针赋值的合法性或非法性是编译器的问题,旧的没有警告你。分配给void *不被视为“非法”可能是因为它是通用的,不可重复的指针类型(它具有未定义的引用大小并且该限制是c语言限制),因此您不能像上面的示例那样接收错误。