繁体   English   中英

C - 不兼容的指针类型分配:为什么会出现警告?

[英]C - Incompatible pointer type assignment: why is it a warning?

我正在看 K&R 第 2 版,它说(在第 5.4 节中):

除了 void *,将一个类型的指针分配给另一种类型的指针而不进行强制转换是不合法的。

但是,执行此操作时,gcc 和 clang 只会发出警告,而不是编译器错误:

int *ip;
char *cp;

ip = cp;

我在 gcc 手册上没有看到任何说明这是默认编译器扩展的内容。 使用 C++ 编译器确实会引发编译错误。

请注意,这本书在 A6.6 节中似乎自相矛盾,它说

指向一种类型的指针可以转换为指向另一种类型的指针。

尽管我给了它怀疑的好处,因为它可能指的是使用显式强制转换从指针类型转换为另一种。

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*值(例如,由于 alignment),它可能会导致未定义的行为。

K&R 中的描述是正确的,尽管措辞有点不正式。 它说:

除了 void *,将一个类型的指针分配给另一种类型的指针而不进行强制转换是不合法的。 如果“合法”是指“不违反约束或语法规则”,这是正确的。 C 标准本身并没有使用“合法”一词,但说某事违反约束与说某事是非法的一样接近。

是的,这个:

指向一种类型的指针可以转换为指向另一种类型的指针。 确实是指使用强制转换的转换——或者在转换为void*的情况下不使用强制转换。

(我个人的偏好是将语法错误和约束违规视为致命错误,但大多数编译器默认情况下相对宽松。这可能是出于历史原因。在语言的早期版本中,将一种类型的指针分配给没有强制转换的另一种类型的指针是有效的,并且从来没有一个好时机通过拒绝旧代码来破坏它。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM