2014-09-02 86 views
0

我读过将指向一个类型的指针指向另一个指向另一个类型的指针是非法的;例如,在本书中:指针转换

C How To Program 7 ed。 PAG。 299

常见编程错误7.7 分配一个类型的指针 指针另一种类型的,如果两者都不是类型为void *的是一个语法错误 。

或在此URL

但豪尔在C11标准被写入:

一个指向对象类型可被转换成一个指针指向一个不同 对象类型。如果生成的指针不正确 为引用类型对齐,行为是未定义的。 否则,当再次转换时,结果应该等于 与原始指针。

所以我明白,只有在存在对齐问题的情况下,行为才是未定义的。

事实上,像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

也许你可以告诉我们这些“很多书”是什么,他们实际上说了些什么?你使用的是什么版本的gcc,以及它给出了什么样的警告。并且告诉我们你在调整方面所做的研究,以及你不了解哪些部分。 – Useless 2014-09-02 12:06:36

+0

@Useless,我不明白是否将指针指向指向另一个类型的指针的类型是LEGAL或NOT,与void *一样。对于标准,它似乎明白它是合法的...... – xdevel2000 2014-09-02 12:23:41

+0

如果本书说分配指向另一种不同类型的指针是“语法错误”,那么这本书是错误的! – Jay 2014-09-02 13:04:58

回答

2

您可以将指针视为内存中指向数据的偏移量,而不管它是哪种类型。任何标准指针(不是智能指针)都有固定大小,取决于系统(32位或64位)。所以你可以将它们分配给其他的,现代编译器会警告你有关危险的操作,但问题是当你试图解除引用不兼容类型的指针时。提领时,应用程序查找对应尖型的字节数,所以在反引用的pB下面的例子

int b = 10; 
int* pB = &b; 
double* pA = pB; 

你会得到10(INT的大小为4个字节),并在解引用爸爸,你会得到垃圾或者因为接下来的4个字节(double是8个字节)可能是为另一个变量分配的内存空间。

结论:在将指针类型分配给彼此时跟踪指针类型,特别是如果您间接指定它们,则使用void *作为中介。 指针赋值的合法性或非法性是编译器的问题,旧的不会警告你。分配给void *不被认为是“非法的”,可能是因为它是通用的,不可指向的指针类型(它具有未定义的引用大小,并且该限制是c语言限制),所以不能像上面的示例那样收到错误。