【问题标题】:Stray # in C headerC 标头中的杂散#
【发布时间】:2021-08-04 22:29:13
【问题描述】:

我正在使用 C99 编译器编译的一些正在运行的遗留 C 代码,我在头文件中间的一个空行上遇到了一个“#”(哈希符号)。我使用 -Wall、-Werrors 和 -pedantic 进行编译,但运行我的单元测试的 GCC 编译器或我的目标交叉编译器没有收到任何投诉。我对语言和预处理器的 BNF 语法进行了快速谷歌搜索,但无法弄清楚流浪 # 会发生什么。它恰好在第 1 列,但如果我将它移到第 2 列,它仍然不会发出任何警告。 我的 GCC 编译器是 gcc(Rev1,由 MSYS2 项目构建)9.1.0。

真的不是问题,只是出乎意料。

有人有什么见解吗?

【问题讨论】:

  • 如果您有 c 问题,请不要添加 c++ 标签。如果您确实想知道 c++ 的规则,请参阅stackoverflow.com/questions/62076620 这里的规则恰好基本相同,因为它涉及预处理器,但您仍然不应该对这些语言进行双重标记。
  • 我认为 C++ 标签在这里是合适的,因为我们经常在我们的标题中使用#ifdef __cplusplus hack。 (在嵌入式框架中很常见)和预处理器是非常接近的表亲。不过谢谢你的提醒。

标签: c c-preprocessor


【解决方案1】:

问题 0:“我在头文件中间的空行中遇到了一个 '#'(哈希符号)。”

C 2018 6.10.7(“空指令”)1 说:

表单的预处理指令

#换行

没有效果。

问题 1:“它恰好在第 1 列,但如果我将它移到第 2 列,它仍然不会抛出任何警告。”

C 2018 6.10 2 表示预处理指令的 # 标记

... 是源文件中的第一个字符(可选地在不包含换行符的空格之后)或在包含至少一个换行符的空格之后。

因此,# 可能出现在文件开头的空格之后或新行开头的空格之后。

请注意,空白序列在很大程度上超出了 C 的形式语法(相反,它们在必要时在文本中解决,如上所示),并且它们包括在处理早期已被空格替换的 cmets。所以预处理指令也可以遵循 cmets。

【讨论】:

  • 酷,感谢您的参考。以前没见过。
  • 而且,根据§5.1.1.2 Translation phases,cmets 在第 3 阶段被空格替换,在第 4 阶段处理预处理指令,因此 cmets 可以在一行中优先于预处理指令。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
  • 2018-09-28
相关资源
最近更新 更多