是否有一种标准方法可以在编译时检查文件是否仅被预处理?

Is there a standard way to check at compile time that file is being preprocessed only?

上下文:不支持除__MY_CC__之外的所有编译器。但是,如何只允许使用第 3 方编译器进行预处理?

#if     cc -E
/* permit only preprocessing with a 3rd-party compiler */
#elif   ! __MY_CC__
#error  unsupported compiler
#endif

更新。我试图解决的潜在问题:

  1. 考虑名为 t0.c.

    的源文件
  2. t0.c的要求:

    一个。 t0.c 只允许使用 my_cc 编译器进行编译。不支持其他编译器(因为 t0.c 包含特定于目标的代码)。

    b。 t0.c 也包含一些元信息。元信息在 t0.c 预处理后可用。

    c。元信息将在没有 my_cc 编译器的环境中使用。 (这意味着 t0.c 不仅被设计为被编译,而且被设计为仅被预处理,即 w/o 执行后续翻译阶段。)因此, t0.c 需要被允许使用任何符合规范的实现(以下称为 cc)进行预处理,而不是 my_cc.

  3. 如何满足这样的要求?

用户 Paul Hankin 提出了以下方法:

#if   ! __MY_CC__
"compiler not supported"
#endif

此代码:

  1. 将与 my_cc 一起编译。好。
  2. 不会用 cc 编译,因为语法错误(例如 clang 给出的):
t0.c:4:1: error: expected identifier or '('
"compiler not supported"
^
1 error generated.

很好。

  1. 使用 cc -E 进行预处理后,生成的翻译单元将包含 "compiler not supported",这是不可取的,因为:

    一个。预计翻译单元不包含任何额外的开销(例如字符串)。

    b。它违反了要求: cc -E 支持的。

不好。

我们可以把"compiler not supported"改成"compilation using non __MY_CC__ is not supported"。但是,预计在 t0.c 被预先拥有之后,生成的翻译单元不包含任何额外的开销(例如字符串)。是否有任何开销较少的解决方案?

没有标准的方法来请求“仅预处理器”编译。事实上,没有关于“仅预处理器”编译可能做什么的标准定义,因为标准 (a) 不强制要求预处理是编译器的一个可分离模块,并且 (b) 在定义预处理器阶段的范围内, 要求预处理阶段后的结果是不带空格的标记序列,这与字符序列不同。

既然如此,肯定没有标准的方法来检测给定的编译器是否在做一些非标准的事情,比如伪造预处理输出。

如果您实际上并不关心 100% 的可移植性,您可能可以使用构建脚本最轻松地做到这一点。