C 标准仅使用术语“诊断”。警告和错误之间没有区别。
没有强制转换的const int *
to转换int *
是需要诊断的约束违规。
这将其与语法错误归为同一类别:您的代码不是有效的 ISO C 程序,并且如果它被翻译并执行,则行为未定义。
不幸的是,许多编译器没有将所需的诊断与他们添加的额外诊断区分开来,更糟糕的是,他们有时需要将诊断作为警告。这是允许的:C 标准没有规定必须阻止需要诊断的程序翻译和执行。通过发出警告,编译器满足诊断要求,仅此而已。
另一个问题是,许多 C 编译器甚至不接受标准的 ISO C 方言,除非他们被要求,而是接受他们自己的方言,这些方言可能有不符合标准(即不向后兼容)的扩展。
GNU C 编译器可以理解一种称为 GNU C 89 的 C 方言,如果你不给它任何方言选项的话。
const int *
因此,具有讽刺意味的是,在这种方言中,转换为没有演员表只是一个警告int *
,而某些合法的 C90 程序则被完全拒绝。
所以基本上你总是必须了解如何控制编译器的输入方言,并跟进所有你必须自己理解的警告,无论它们是真正违反语言,还是只是编译器的突发奇想writers(“建议在这个表达式周围加上括号”)。
编译不是一个坏主意gcc -Wall -W -ansi
(如果您在 C90 中编程;或者-std=c99
代替ansi
C99)并确保没有警告。甚至那些建议额外括号之类的文体也没有。如果您没有足够的纪律来跟进警告,请添加-Werror
将它们变成使您的构建失败的错误。有些人还会推荐-pedantic
。
如果你遵循这个原则,a 的颠覆const int
就不会潜入你的代码库。