为什么以及如何像 Python 或 Java 这样的语言能够显示精确且易于理解的错误消息,而真实且经过测试的长期 C/C++ 编译器显示神秘且通常不相关的错误消息?
3 回答
这不是语言;这是编译器的时代。自 1970 年代后期 Unix 开始进入大学以来,C 一直是事实上的标准。Microsoft Windows 的市场渗透只是加强了这一标准。因为 C 是标准,所以没有人必须编写一个好的编译器来让人们使用它。在 1970 年代和 1980 年代的机器上,生成漂亮的错误消息需要时间和空间,而这些时间和空间被认为是宝贵的资源。即使错误消息很糟糕,人们也非常高兴获得免费的 C 编译器。
来自旧 C 编译器的错误消息非常糟糕,以至于有人拿它们开玩笑;这是来自Unix Haters 手册的第 2 章:
肯汤普森有一辆他帮助设计的汽车。与大多数汽车不同,它既没有速度表,也没有油量表,也没有其他困扰现代驾驶员的众多白痴灯。相反,如果司机犯了错误,一个巨大的“?” 在仪表板中央亮起。“经验丰富的司机,”汤普森说,“通常会知道问题所在。”</p>
到 1990 年代,当更新的语言传播时,机器速度更快,内存更多,提供良好的错误消息是提高思维共享的一种方法。
如果您尝试使用相对较新的 C 编译器,例如clang,您会发现它会产生极好的错误消息 — 有时甚至包括突出显示和颜色。(我敢打赌来自 Visual Studio 的错误消息也很好,但我不确定。)
编译时错误
由于条件编译(预处理器、宏)以及非常强大的模板(比例如 C# 或 Java 更通用),编译时错误通常很神秘。
然而,这一切都取决于编译器,例如较新的 CLang 声称更多可读的错误消息。
在我看来,开发是顺序的,错误的行号通常就足够了(我真的不需要阅读错误信息)。
运行时错误
性能: C/C++ 具有“零开销”目标,因此例如函数名称被剥离,函数被内联。许多错误是“未定义的行为”,以允许更快的实施。它还允许您进行几乎任何事情 - 甚至是危险的操作 - 不受限制。
并非如此:许多 C++ 编译器可以在异常时产生堆栈跟踪。
我认为这可能是因为对编程风格/可能性/语法等施加了额外的限制(这对于 C/C++ 等旧语言来说非常困难,因为需要向后兼容)。例如,更严格的约束最大限度地减少潜在错误类型的数量,从而简化精确的错误检测。