为什么C编译器在行之后给出错误,而不是在它们之上?

当我和我的编译器进行了另一次国内事务时,这个问题在工作中突然出现在我的脑海里.尽管我的小女孩(由于我在工作中的所有分号),我设法在一个if语句之前想念一个.显然,这导致编译错误

error C2143: Syntax error : missing ‘;’ before ‘if’

所以我想知道“好吧,你为什么不能告诉我,这个问题后面没有分号,而不是分行.”我继续尝试其他类似的语法错误

error C2065: ‘myUndeclared’ : undeclared identifier

error C2143: Syntax error : missing ‘)’ before ‘if’

etc…

现在,所有这些错误,同样地,在问题之后带我走上阵线,并抱怨在if语句之前.

考虑以下几点:

SomeFunction(x) //Notice,there is no ';' here

if(bSomeCondition)
{
    ...
}

我得到两个编译错误

(Line 265) error C2065: ‘x’ : undeclared identifier

(Line 266) error C2143: Syntax error : missing ‘;’ before ‘if’

但是,尽管缺少分号,第一个错误正确地告诉我行号.这对我来说,编译器在解析时不会跳起来,并且能够使其超过分号问题.那么为什么编译器坚持以这种方式报告语法错误呢?其他错误(非语法)在其发现的线上报告.这是否与编译器进行多次通过有关?基本上,我希望具有C编译器工作知识的人可以具体说明编译器正在做什么,因此必须以“之前”的方式报告错误.

解决方法

对于“为什么C/C++错误消息吮吸”的更一般性问题的简短答案是“有时C真的很难解析”(实际上没有上下文无关的语法).然而,这不是真正的有效理由 – 仍然可以使工具比大多数C编译器记录更好的诊断信息.

更实际的答案是“编译器作者已经继承了不重视错误消息的遗留代码库”,结合轻度剂量的“编译器作者懒惰”,其中“诊断报告不是一个令人兴奋的问题”.大多数编译器编写者将添加一种新的语言特性或3%的代码性能改进,而不是对代码库进行重大重构以允许体面的错误报告.关于“为什么没有将错误正确定位到导致”他们“的行的具体问题就是这样的一个实例.编译器一般不会出现这样的一个技术原因:不见了
,然后告诉你最后一个源的跨度;缺乏声明 – 即使在C的一般空格不变性的存在下.只是存储这些信息(在很大程度上)在历史上被忽略.

也就是说,几十年的旧代码没有阻碍的新编译器做得更好.看看Clang compiler,它对自己的合理错误信息感到自豪. page on diagnostics显示出比GCC好多了.这种情况的一个例子是:

$gcc-4.2 t.c
  t.c: In function 'foo':
  t.c:5: error: expected ';' before '}' token
  $clang t.c
  t.c:4:8: error: expected ';' after expression
    bar()
         ^
         ;

或者更令人印象深刻:

$cat t.cc
  template<class T>
  class a {}
  class temp {};
  a<temp> b;
  struct b {
  }
  $gcc-4.2 t.cc
  t.cc:3: error: multiple types in one declaration
  t.cc:4: error: non-template type 'a' used as a template
  t.cc:4: error: invalid type in declaration before ';' token
  t.cc:6: error: expected unqualified-id at end of input
  $clang t.cc
  t.cc:2:11: error: expected ';' after class
  class a {}
            ^
            ;
  t.cc:6:2: error: expected ';' after struct
  }
   ^
   ;

看,甚至告诉我们什么键入哪里可以解决问题! < / clang_salespitch>

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...