【问题标题】:Why does this compile without an error with Visual Studio and not GCC?为什么使用 Visual Studio 而不是 GCC 编译时没有错误?
【发布时间】:2015-10-13 13:22:23
【问题描述】:

您知道为什么使用 Visual Studio (2012) 而不是 GCC 4.7.2 编译时没有错误吗?

我正在对棘手的源文件进行一些编译器测试。 根据接受的答案here,GCC 不应该出错(错误:/ 标记之前的预期表达式):任何紧跟换行符的反斜杠字符 () 以及换行符都会被删除。 所以,这相当于线拼接,应该作为单线进行预处理。

#include                                        \
                                                \
    "my_header_\
file_example.h" /* this is a long trailing\
                comment */

【问题讨论】:

  • 在这里工作。也许你有 \r\n 问题?
  • 这里有一点关于反斜杠和翻译阶段的行延续stackoverflow.com/questions/7059549/…,其中一个答案是关于在反斜杠后无意中添加空格的棘手问题。
  • @djondal 在此处发布错误消息将有助于 1) 理解问题 2) 更好地搜索指向此处的其他有相同问题的人。

标签: c visual-studio gcc


【解决方案1】:

如果您在\ 之后确实有一个行尾立即,则源代码如果正确并且应该被符合标准的编译器接受。 C99 语言草案在 5.1.1.2 翻译阶段中说:

§2: 每个反斜杠字符 (\) 的实例都被删除,紧跟一个换行符,将物理源代码行拼接成逻辑源代码行。 只有任何物理源行上的最后一个反斜杠才有资格成为此类接头的一部分。非空源文件应以换行符结尾,在任何此类拼接发生之前,该换行符之前不应紧跟反斜杠字符。

这实际上发生在第 2 阶段 预处理器执行任何 #include 之前,因此它应该根据标准被接受:

§4: 预处理指令被执行,宏调用被扩展,并且 _Pragma 一元运算符表达式被执行。如果一个字符序列 匹配通用字符的语法名称由令牌产生 连接(6.10.3.3),行为未定义。 #include 预处理 指令使命名的头文件或源文件从阶段 1 开始处理 通过第 4 阶段,递归。

但是,如果\ 和行尾之间有空格,则不会发生§2 的操作,并且会出现错误。

【讨论】:

    【解决方案2】:

    在宏中忽略反斜杠/换行符组合是正确的(宏延续)。但是,这发生在字符串中。反斜杠后面不是n 或其他定义的转义字母,而是0x0d 或0x0a,然后将其按字面意思放入字符串中。所以它试图打开的文件类似于my_header_0x0dfile_example.h。

    顺便说一句,知道它给出的错误很有趣。正如我在上面所怀疑的那样,它抱怨找不到文件,而不是“字符串文字中的非法'\'”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-18
      • 2014-04-25
      • 1970-01-01
      • 2020-06-27
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多