【问题标题】:What does a C++ preprocessor do when there's just a single `#` in a line - and nothing else?当一行中只有一个 `#` 时,C++ 预处理器会做什么 - 没有别的?
【发布时间】:2020-09-16 11:19:30
【问题描述】:

这是一个有效的 C++ 行吗?应该是什么意思?

#

这个呢:

# // a comment

最近的编译器似乎忽略了它,没有错误也没有警告。

它“什么都不做”吗?我有一个头文件,其中在存在此类行的情况下使用 g++ 7.4.0 编译时会出现“兼容性”部分。在非活动的#if 分支中看到这一行被排除在外的编译器似乎不会出错。

注意:Travis CI 上的 Debian Bionic(撰写本文时)上的 gcc 7.4.0 会被此类行绊倒。

【问题讨论】:

  • 编译器为什么会“跳闸”。一些文本编辑器在文件结束标记之前编写没有行结束标记的文本文件。这可能会导致一些较旧的 C 或 C++ 预处理器无法读取文件的最后一行。我记得一个预处理器坚决无法识别编辑文件时明显存在的#endif(关闭包含防护)。修复是在#endif 之后的一个额外的空白行(或带有“不要删除此行”的注释的行)。有关信息,请参阅stackoverflow.com/questions/2287967/…
  • @Peter 好提示!就我而言,# 早于最后一行。
  • 虽然我描述的行为看起来不同,但它是源/头文件的内容可能看起来正确的一个示例,但会导致预处理器出错。在它被隔离之前,当项目源在 unix 和 windows 机器之间复制(并通过unix2dos() 或dos2unix(),取决于复制的方向)然后构建时,我描述的示例引起了头痛。我不禁想知道您是否遇到过类似的问题 - 找到比文本编辑器检查文件的“更低级别”的方法可能会提供一些线索。
  • 哦,不只是旧的 gcc 错误,仅此而已。

标签: c++ language-lawyer c-preprocessor


【解决方案1】:

这两个例子都是有效的,它们什么都不做。

对于第二个示例,首先删除 translation phase 3 中的 cmets:

... 每个注释都被一个空格字符替换。保留换行符。 ...

导致第一种情况,这是在translation phase 4中扩展的预处理器指令:

执行预处理指令,...

这个预处理器指令是有效的,被称为Null directive,并且没有效果,如here所述:

表单的预处理指令

#换行

没有效果。

new-line 是字面上的换行符。

所以您显示的代码是有效的,应该被符合要求的实现所接受。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-01
    • 1970-01-01
    相关资源
    最近更新 更多