我对C-Code中编码器警告的经验假设实际上是他们警告实现定义的行为类型,或者他们检测到导致未定义行为的构造的情况,然而他们支持这种行为(如果他们检测到并且他们不会因为警告而抛出错误。)
在我讨论了这个之后,最后证明我错了:
#include <whatever_this_needs.h>
int main()
{
int i = 50;
return 0;
}
编译器明显警告i
已声明但从未使用过。
我不再考虑这种警告,因为我更多地将它们视为一种工具......一种信息。
虽然我会严格地将这种警告与那些警告我没有显式强制转换而导致不可移植性或降低重要性的警告分离,但它仍然会引起编译器优化的混淆。
所以我现在感兴趣:警告类型是否有任何分类? 如果没有关于它的标准存在,那么GCC会将它们的警告分组?
到目前为止我注意到了(经验再次):
但特别是第二点困扰我,因为有一些结构(即严格的别名规则),其中优化甚至可能导致不可预测的运行时行为,而大多数情况下它只是削减了无论如何都没有使用的代码。
我的观点是否正确?还有哪些(额外的)官方类别,你可以&#39; typecast&#39;警告,它们的特征是什么,它们的影响是什么?
答案 0 :(得分:5)
警告超出了C标准的范围,因此对于它们的行为方式没有要求或规范。 C标准只关注 diagnostics ,就像从编译器到程序员的诊断消息一样。该标准不会将其分解为错误和警告。
但是,所有编译器都使用错误来指示直接违反C标准:语法错误等。他们使用警告来指出超出C标准所要求的内容。
几乎在所有情况下,警告只是意味着“哦顺便说一下,你这里有一个错误”。
关于GCC(see this),它只是将警告分类为:
系统背后没有明显的逻辑。
请注意,GCC被填充到非标准扩展的边缘,已决定仅针对某些C标准违规发出警告而不是错误。因此,如果您关心标准合规性,请始终使用-pedantic-errors进行编译。
关于实现定义的行为:C包含很多,如果你得到每个这样的情况的警告(“警告:使用了两个补充int”,那将会非常繁琐) )。实现定义的行为和编译器警告之间没有关系。
对于任何未定义行为的情况,编译器通常无法检测到它,因为UB的定义是超出标准范围的运行时行为。因此,了解和避免UB的责任在于程序员。