C++ 什么是编译器诊断?

C++ 什么是编译器诊断?,c++,compiler-errors,language-lawyer,compiler-warnings,C++,Compiler Errors,Language Lawyer,Compiler Warnings,我通常说“编译器警告”,“编译器错误”。因此,当听到“编译器诊断消息”或只是“编译器诊断”时,我有点不确定它们是否只是常见的“编译器警告”、“编译器错误”或其他信息?标准实际上将诊断消息定义为 属于实现定义的消息子集的消息 实现的输出消息 这是实现选择呈现的任何形式的任何消息。打印到console的警告和错误都属于此定义。但它不仅限于控制台,甚至不仅仅是警告或错误。例如,实现可以选择在弹出窗口中显示“info”消息。这也是一个潜在的诊断信息。< P>诊断信息是C++标准中的一个艺术术语。当有人

我通常说“编译器警告”,“编译器错误”。因此,当听到“编译器诊断消息”或只是“编译器诊断”时,我有点不确定它们是否只是常见的“编译器警告”、“编译器错误”或其他信息?

标准实际上将诊断消息定义为

属于实现定义的消息子集的消息 实现的输出消息

这是实现选择呈现的任何形式的任何消息。打印到console的警告和错误都属于此定义。但它不仅限于控制台,甚至不仅仅是警告或错误。例如,实现可以选择在弹出窗口中显示“info”消息。这也是一个潜在的诊断信息。

< P>诊断信息是C++标准中的一个艺术术语。当有人说“编译器诊断”时,他们很可能在模糊地思考这个术语,但没有正确地应用它

对于代码中不符合标准要求的内容,标准有几个类别,允许编译器响应的方式取决于错误属于哪个类别

本标准中的大多数要求都在“可诊断规则集”中。这些规则包括标准中的所有语法和语义要求,但明确标记为“无需诊断”的规则和被描述为导致“未定义行为”的规则除外。(这是来自[intro.compliance]/1)

如果程序违反了可诊断规则,则一致性实现“应发出至少一条诊断消息”

因此,从广义上讲,大多数编码错误都需要诊断信息。现在,什么构成“诊断消息”的问题还没有解决,在标准中定义为“属于实现定义的实现输出消息子集的消息”

这意味着编译器可以随心所欲地与您交谈,也可以随意交谈,只是当检测到某些编码错误时,它必须对您说些什么

因此,当编译器告诉您应该在
if(a&&b | | c&&d)
中的
|
操作周围添加括号时,这只是胡说八道。代码是有效的,它的含义是明确定义的,它只是给你一些风格上的建议(而且是糟糕的建议)

当它告诉您它不知道
typedef int foo中
x
的类型时;fox它正在响应可诊断错误。如果实现的文档告诉您该消息是诊断消息,那么它就是诊断消息。一般来说,编译器就是这么做的

请注意,编译器不是拒绝编译具有可诊断错误的代码所必需的。唯一的要求是发出诊断信息。完成后,编译器可以自由地继续编译代码,并得到特定于实现的结果。这种灵活性的主要原因是它允许特定于编译器的扩展


编译器通常区分警告和错误;这个标准没有。它确实要求,当提供的代码不违反任何标准要求时,并且如果程序不是太大(在模糊的意义上),编译器必须创建一个可执行程序。从形式上讲,这是“如果一个程序没有违反本国际标准中的规则,则一致性实施应在其资源范围内接受并正确执行该程序。”[intro.compliance]/2.

许多标准的价值不仅仅在于它们要求所有一致性实例所做的事情,但在一些事情上,他们建议质量实例应该在实际可行的情况下进行。然而,C89标准的作者不遗余力地避免为任何不需要的东西提供任何这样的建议。例如,如果C89建议实现以与全局传递关系一致的方式处理指针上的关系运算符,那么这可能被视为意味着不可行的实现在某种程度上是次等的


该标准的作者不想禁止一致性实现有效地处理早于该标准且不满足其要求的代码,但也不想特别暗示实现应该接受不满足要求的新代码。一致性实现必须有意义地处理至少一个程序,或者给定源文本的实现违反编译时约束,必须产生至少一个诊断,这是硬需求和建议之间的一种闪避。据推测,一个高质量的实现应该能够有效地处理除单个人为(可能是无用的)源文本之外的其他内容,并且应该生成比“警告:此实现不会输出除此之外的任何诊断”更有用的诊断,但是一个实现可以在不超出上述范围的情况下满足标准。

简而言之,它是由编译器生成的所有消息(警告和错误)。标准化一般来说很难,但我觉得这个措辞特别奇怪。为什么要定义子集实现?这是否也允许标准未强制要求的编译器消息被称为“诊断”消息?定义的实现可能指:实现可以选择消息的实际外观。在第一次阅读时,我认为“定义的实现”指的是:实现可以选择输出消息属于subset@formerlyknownas_463035818-我想这实际上是你第一次读对了。实现可能会显示与诊断无关的消息。我认为这个定义只是指出了一个实现