是否有任何类别来表征警告?

Are there any categories to characterize warnings?

我对编译器在 C 代码中警告的经验假设实际上是它们警告实现定义的行为类型,或者在它们检测到导致未定义行为的构造的情况下,它们仍然支持这种行为(如果它们检测到他们不会抛出警告错误)。

在我对此进行讨论之后,我错了的最终证据是:

#include <whatever_this_needs.h>

int main()
{
    int i = 50;
    return 0;
}

编译器明显警告 i 已声明但从未使用过。 我不再考虑这种警告,因为我更多地将它们视为一种工具……一种信息。

虽然我会严格区分这种警告与警告我在没有显式转换的情况下导致可移植性或降低重要性的警告,但它仍然是编译器优化可能导致混淆的警告。

所以我现在很感兴趣:是否有任何警告类型的分类? 如果没有关于它的标准,GCC 将警告分为哪些类别?

到目前为止我注意到的(再次经验):

但尤其是第二点让我感到困扰,因为在某些构造(即严格的别名规则)中,优化甚至会导致不可预测的运行时行为,而大多数情况下它只是删除了无论如何都不使用的代码。

所以我的观点正确吗?您可以在哪些(其他)官方类别中 'typecast' 发出警告,它们的特点是什么,它们的影响是什么?

警告超出了 C 标准的范围,因此对于它们的行为方式没有任何要求或规范。 C 标准只关心 诊断 ,如从编译器到程序员的诊断消息。该标准不会将它们分为错误和警告。

但是,所有编译器都使用错误来指示直接违反 C 标准:语法错误和类似错误。他们使用警告来指出超出 C 标准要求的内容。

在几乎所有情况下,警告仅表示 "oh by the way, you have a bug here"。


关于 GCC (see this),它只是将警告分类为:

  • 直接违反 C 标准但作为 non-standard GNU 扩展(-pedantic)有效的内容
  • "A handful of warnings"(-墙)。启用所有警告,除了一些...
  • "A few warnings more" (-Wextra)
  • 加上许多没有类别的单独警告。

系统背后没有明显的逻辑。

请注意,GCC 被 non-standard 扩展填满了,决定只对某些违反 C 标准的行为给出警告而不是错误。因此,如果您关心标准合规性,请始终使用 -pedantic-errors 进行编译。

关于 implementation-defined 行为:C 包含 很多 这样的行为,如果您对每个此类情况都收到警告,那将变得非常乏味("warning: two's complement int used"...)。 implementation-defined 行为与编译器警告之间没有关系。

对于任何未定义行为的情况,编译器往往无法检测到,因为UB的定义是超出标准范围的运行时行为。因此,了解和避免 UB 的责任在于程序员。