【问题标题】:What are the differences between the C and C++ preprocessors? [duplicate]C 和 C++ 预处理器之间有什么区别? [复制]
【发布时间】:2014-02-02 20:11:58
【问题描述】:

C 和 C++ 预处理器之间的行为有什么不同吗?

它们由不同的标准文本段落定义(C standard 的第 6.10 节和C++ standard 的第 16 节)。

我提出这个问题的动机是,最近被 C++14 接受的 proposal for making the single quote a digit separator 扩展了 C++ 预处理器语法以适应这种变化(具体来说,它扩展了 pp-number),我想知道这是否会导致 C 和 C++ 预处理器之间的不兼容,如果是,这是否是第一个这样做的功能。

【问题讨论】:

  • GCCg++(实际上是cc1plus)和gcc(实际上是cc1)使用相同的libcpp/ 内部库进行预处理。
  • 这个答案给出了一些已经存在的差异的例子:stackoverflow.com/questions/5085533/…
  • 您可以随时查看可变参数宏。 C在C99中有它们。 C++ 必须等到 C++11。

标签: c++ c c-preprocessor standards


【解决方案1】:

C 和 C++ 处理器之间存在一些差异。忽略预定义宏和可用系统头文件的差异,当前 C 和 C++ 版本中的一些差异是:

  • and 和朋友是 C++ 中的运算符,而不是标识符。这意味着 #define and && 在 C 中有效,但在 C++ 中无效,并且意味着 #if 1 and 2 在 C++ 中有效,但在 C 中无效(除非 and 被适当地定义为宏)。
  • falsetrue 在 C++ 中允许使用 #if 表达式,但在 C 中被 0 (与所有标识符一样)替换。这意味着 #if true/C++/#else/C/@987654333 @ 扩展为 C++C,具体取决于语言。不过,与and 和朋友们不同的是,它们不是运算符,因此可以由#define 在任一语言中重新定义。
  • ::.*->* 是 C++ 中的标记。因此,## 运算符可用于在 C++ 中形成它们,但不能在 C 中。
  • 原始字符串文字在 C++ 中可用,但在 C 中不可用。因此,给定宏 fooR"x("foo")x" 在 C 中扩展宏,但在 C++ 中不扩展。
  • 十六进制浮点常量在 C 中可用,但在 C++ 中不可用。因此,给定一个宏 foo0x1p+foo 会在 C++ 中扩展该宏,而不是在 C 中。

【讨论】:

  • @JensGustedt + 仅允许作为 pp 编号的一部分,如果它遵循 eE (C++),或 eEpP (C)。如果无条件允许,1+2 将无效。 (0xE+0xF 已经因为同样的原因无效,这已经有点问题了。)
  • @hvd: falsetrue 是 C++ 中的关键字,而不是 C 中的关键字。
  • 在 C 中,将关键字定义为宏名称具有未定义的行为(N1570 6.4.1p2;它是约束之外的“应”)。因此,符合标准的 C 或 C++ 预处理器可以将关键字视为普通标识符(我不太确定 C++ 规则)。
  • @hvd:关键字和运算符不是专有类别。 sizeof 是用作运算符的关键字。 andor等与关键字分开列出,但它们是“保留的,不得用于其他用途”;我不确定标准在这些替代表示和实际关键字之间有什么区别。
  • @KeithThompson 它说“上述标记(区分大小写)被保留(在翻译阶段 7 和 8 中)用作关键字,不得在其他情况下使用。”,这确实允许在其他情况下使用其他翻译阶段,除非我看错了。
猜你喜欢
  • 2012-09-28
  • 2014-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 2022-09-24
  • 2012-08-11
相关资源
最近更新 更多