为什么C++编译器的错误信息晦涩难懂?

4

为什么C++编译器(以及其他编程语言的编译器)的错误信息相当晦涩?这是历史原因吗?还是懒惰?或者对于所有人来说制作清晰的错误信息太难了?

模板错误产生的错误信息可能会非常恼人/令人生畏。此外,错误消息可能使用非直观的缩写,例如“静态成员函数不能有cv限定符。”我认为“cv”代表常量/易失性。


3
现代编译器通常会生成相当好且明确的错误消息。它们假设您知道自己正在编写的语言,但仅限于此。至于“cv-qualifier”,那是C++标准使用的技术术语(例如,在2011年标准中的§3.9.3 CV-qualifiers [basic.type.qualifier])。是的,它意味着“const或volatile限定符”。 - Jonathan Leffler
没关系。虽然模板错误会生成一堵文本墙,但唯一重要的是第一个错误的有问题的行号,我从不关注它说了什么。 - Non-maskable Interrupt
2
C++没有错误信息。编译器实现有错误信息。因此,针对每种情况,您的问题应该被提交给实现者。 - user207421
抱歉,大家都是对的,产生错误消息的是编译器,而不是C++。 - J-Win
1个回答

11

首先,导致你收到错误信息的不是C++语言本身,而是你所使用的编译器。这听起来可能很学术,但这是一个重要的区别。虽然编译器诊断在所有主流实现中都非常复杂,但这并不会影响你的问题。

编译器错误信息之所以如此准确和精确,不是因为懒惰或历史原因,而是由于以下原因的综合影响:

  • 追求精确性

    为了不仅让一些新手能够理解,而导致那些真正的专业人士无法获取有用的信息,我们不能简化描述。例如,在你的示例中,“cv-qualifier”是准确和精确的,可以告诉你发生了什么。你可以采用其他方式进行描述,但这要么不能实际映射到正在使用的语言方面,要么就是错误的。

  • 实现复杂性

    诚然,模板诊断可能非常糟糕。近期GCC版本、Clang以及STLFilt等工具已经进行了改进,但最终,这很难做到。如果你认为自己可以做得更好,请随时向你喜欢的实现提交一个补丁。 :)

  • 语言复杂性

    C++语言非常复杂,这是它的本质所在。它非常强大,要比一些小型脚本语言或其他提供更好信息的语言更加强大。有人可能会认为其构造过于复杂,这是对该语言的常见批评。可以说,需要进行复杂而精确的诊断至少部分源自于此。

  • 无法读取思维

    这是第一个因素的变化。为了产生一组更简单的错误消息,编译器必须知道当你的代码出错时,你打算写什么。这是不可能的,除非能够读取你的心思。编译器可以试图猜测,但风险是猜测会出错。事实上,在像C++这样复杂的语言中,这种风险相当高。因此,我们更喜欢编译器直接告诉我们,然后我们训练自己的大脑将诊断与我们编写的代码进行匹配;一个专业的C++开发人员通常可以在几秒钟内认识到特定错误消息(由特定代码触发)的原因......即使该错误消息在表面上看起来完全无用。这就是我们行业的魔力!


存在着“错误报告简化器”,例如旧版的stlfilt。理想情况下,编译器应该进行这样的处理,并使用源代码更详细的知识来命名事物,例如函数式编程中的where子句。我猜主要原因是由于管理和开发的资源有限。例如,g++输出与错误消息相关的信息作为后续行,如果您要求它在第一个错误时停止,那么这些信息就会被抑制,而这种质量的缺乏本应很容易修复。 - Cheers and hth. - Alf
我理解你的观点。准确是好的,但我一般不喜欢使用非直观的缩写。将 cv 限定符扩展为常量/易失性限定符可以实现大致相同的目的。 - J-Win
@J-Win: "cv-qualifier" 不仅是标准中逐字引用的精确术语,而且对于C++开发人员来说非常直观,因为他们知道它的含义。那些不知道的人只需要查一次就可以了。每次都完整地写出来会使消息在技术上不够正确,更加烦琐冗长,因此最终变得不太有用。 - Lightness Races in Orbit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接