预处理器相等性测试,这是标准吗?

Posted

技术标签:

【中文标题】预处理器相等性测试,这是标准吗?【英文标题】:Preprocessor equality test, is this standard? 【发布时间】:2012-10-30 23:42:33 【问题描述】:

我曾在项目偏好中设想过其中之一

TESTING = HOST TESTING = TARGET TESTING 根本没有定义

我的问题是后者。

似乎不是

#if TESTING==HOST
#error "HOST defined"  // add temporarilly for testing porpoises
#endif

我需要编码

#ifdef TESTING   
#if TESTING==HOST
#error "HOST defined"  // add temporarilly for testing porpoises
#endif
#endif

我确信这不是标准行为,因为如果未定义 TESTING,那么它肯定不等于 HOST,而且我不需要 GCC 编译器额外的 #ifdef TESTING

但是,当我使用 Atmel AVR Studio(我认为基于 MS Visual Studio)时,有必要在几十个地方添加初始 #ifdef TESTING :-(

看起来我别无选择,但我只是想知道是否有任何 C 标准真的需要这个。

【问题讨论】:

【参考方案1】:
#if TESTING==HOST

如果TESTING没有定义,那么

相当于:

#if 0==HOST

来自 C 标准:

(C99, 6.10.1p4) "由于宏扩展和定义的一元运算符执行了所有替换后,所有剩余的标识符(包括那些在词法上与关键字相同的标识符)都被替换为 pp-number 0""

【讨论】:

在这种情况下,如果@Mawg 将HOST 定义为1 并将TARGET 定义为2,那么如果TESTING 未定义,他对#if TESTING == HOST 的原始测试应该会失败,这是正确的? +1 @ouah 那么,如果 TESTING 和 HOST 都没有定义,那么条件是否成立?这就解释了。谢谢 如此处所述:***.com/questions/3852507/…——如果使用带有-Wundef 选项的未定义宏扩展,某些编译器会报告警告。 标准中的引用仅指#if 指令,而不是一般的宏替换。【参考方案2】:

请注意,您可以这样做:

#ifndef TESTING
    ...
#elif TESTING == HOST
    ...
#elif TESTING == TARGET
    ...
#else
    #error "Unexpected value of TESTING."
#endif

还有:

#if defined(TESTING) && TESTING == HOST
    ...
#endif

如果您想折叠测试。括号是可选的(#if defined TESTING 是有效的),但我认为包含它们更清楚,尤其是当您开始添加其他逻辑时。

【讨论】:

【参考方案3】:

原始的 C 预处理器在使用符号之前需要显式的 #ifdef 验证。假设未定义的符号具有默认值是一项相对较新的创新(可能由 javascript 等脚本语言驱动)。

你为什么不总是确保定义了符号?:

#ifndef TESTING
 #define TESTING  (default value)
#endif

#if TESTING==HOST
  ...
#elif TESTING==TARGET
 ...
#else
 ...
#endif

替代,也许强制选择?:

#ifndef TESTING
 #error You must define a value for TESTING
#endif

【讨论】:

C89如何分类?相对较新,还是很古老? C 预处理器的行为在当时是标准化的,它在条件测试中对未定义符号的处理在 1989 年与 1999 年和 2011 年相同。 我认为实践只是一种约定,而不是要求。它允许在编译器命令行(或前面的包含文件)上提供替代定义,覆盖代码中定义的定义。【参考方案4】:

我遇到了同样的问题。如果没有定义我想要的#if 参数,它曾经是编译器会出错。我学到了艰难的方式,这不再是这种情况。我想出的解决方案如下:

#define BUILDOPT 3

#if 3/BUILDOPT == 1
    <compile>
#endif

如果 BUILDOPT 未定义,则除以 0 时会出现编译错误。如果 BUILDOPT != 3 && > 0 则 #if 失败。

【讨论】:

【参考方案5】:

我的最终实现是将 BUILDOPT 设置为 1 以启用代码,> 1 以禁用。那么#if 就变成了#if 1/BUILDOPT==1。

【讨论】:

这应该是对原始答案的编辑,而不是单独的答案。

以上是关于预处理器相等性测试,这是标准吗?的主要内容,如果未能解决你的问题,请参考以下文章

标准预处理器宏

Xcode:测试与调试预处理器宏

使用 CXX 查询预处理器定义?

Visual C ++转储预处理器定义

为啥这个 TF-IDF 情感分析分类器表现这么好?

无视空格的字符串的 Jest 相等匹配器