我在看K&R第二版,上面写着(第5.4节):
这是不合法的..。除void *外,将一种类型的指针分配给另一种类型的指针,而不进行强制转换。
但是,gcc和clang在执行以下操作时只会发出警告,但不会引发编译器错误:
int *ip;
char *cp;
ip = cp;我在gcc手册上没有看到任何关于这是默认编译器扩展的声明。使用C++编译器确实会引发编译错误。
请注意,这本书在A6.6节中似乎自相矛盾。
指向一种类型的指针可以转换为指向另一种类型的指针。
虽然我给它带来了疑问,因为它可能指的是使用显式强制转换将指针类型转换为另一种类型。
发布于 2020-04-17 23:37:29
int *ip;
char *cp;
ip = cp;赋值违反约束,这意味着符合条件的编译器必须发出诊断,就像对语法错误一样。(关于简单赋值的要求,请参见http://port70.net/~nsz/c/c11/n1570.html#6.5.16.1。)这种诊断可以是一个非致命的警告。C标准从不要求拒绝代码,除非它有#error指令。它没有将代码称为“合法”或“非法”。
如果使用gcc -std=c11 -pedantic-errors编译,gcc会将其视为致命错误。请注意,默认情况下gcc并不是一个完全符合C的编译器,尽管在这种情况下它的行为是一致的。
通过强制转换(明确的转换),转让将是合法的:
ip = (int*)cp;但是,如果cp的值是不确定的,或者如果转换导致无效的int*值(例如,由于对齐),则可能会导致未定义的行为。
K&R中的描述是正确的,尽管措辞有点非正式。上面写着:
这是不合法的..。除void *外,将一种类型的指针分配给另一种类型的指针,而不进行强制转换。如果“合法”指的是“不违反约束或语法规则”,则这是正确的。C标准本身并没有使用“合法”这个词,但是说某事是一种违反约束的行为几乎等于说某件事是非法的。
是的,这个
指向一种类型的指针可以转换为指向另一种类型的指针。指的是使用强制转换--或者在转换到和从
void*转换的情况下没有强制转换。
(我个人倾向于将语法错误和约束冲突视为致命错误,但大多数编译器在默认情况下相对宽松。这可能是出于历史原因。在语言的早期版本中,将一种类型的指针分配给另一种类型的指针而不进行强制转换是有效的,并且从来没有通过拒绝旧代码来打破旧代码的好时机。)
https://stackoverflow.com/questions/61282136
复制相似问题