C语言 预处理器相等测试,这是标准吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13149189/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:14:34  来源:igfitidea点击:

Preprocessor equality test, is this standard?

cc-preprocessor

提问by Mawg says reinstate Monica

I had envisaged one of these in the project preferences

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

  • TESTING= HOST
  • TESTING= TARGET
  • TESTINGnot defined at all
  • TESTING= HOST
  • TESTING= TARGET
  • TESTING根本没有定义

My problem is with the latter.

我的问题是后者。

It seems that instead of

似乎,而不是

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

I need to code

我需要编码

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

I am convinced that this is not-standard behaviour, since if TESTINGis not defined then it certainly doesn't equal HOST, and I do not need that extra #ifdef TESTINGwith the GCC compiler.

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

However, when I use the Atmel AVR Studio (which I thinkis based on MS Visual Studio), it is necessary to add that initial #ifdef TESTINGin a few dozen places :-(

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

It looks like I have no choice, but I just wondered if any C standard acually requires this.

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

回答by ouah

#if TESTING==HOST

If TESTINGis not defined, then

如果TESTING没有定义,那么

it is equivalent to:

它相当于:

#if 0==HOST

From the C Standard:

来自 C 标准:

(C99, 6.10.1p4) "After all replacements due to macro expansion and the defined unary operator have been performed, all remaining identifiers (including those lexically identical to keywords) are replaced with the pp-number 0""

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

回答by tomlogic

And note that you can do this:

请注意,您可以这样做:

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

Also:

还:

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

If you want to collapse the tests. The parenthesis are optional (#if defined TESTINGis valid) but I think it's clearer to include them, especially when you start adding additional logic.

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

回答by wallyk

The original C preprocessors required explicit #ifdefvalidation before using a symbol. It is a relatively recent innovation (perhaps driven by scripting languages like Javascript) to assume that undefined symbols have a default value.

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

Why don't you always insure the symbol is defined?:

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

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

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

Alternative, maybe force a selection?:

替代方案,也许强制选择?:

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

回答by jdavis

I had the same problem. It used to be the compiler would error if the #if parameter was not defined which is what I wanted. I learned the hard way this is no longer the case. The solution I came up with is as follows:

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

#define BUILDOPT 3

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

If BUILDOPT is not defined you get a compile error for divide by 0. If BUILDOPT != 3 && > 0 the #if fails.

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

回答by jdavis

My final implementation is to set BUILDOPT to 1 to enable the code, > 1 to disable. Then the #if becomes #if 1/BUILDOPT==1.

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