Preprocessor equality test, is this standard?

不羁岁月 提交于 2020-03-17 06:57:06

问题


I had envisaged one of these in the project preferences

  • TESTING = HOST
  • TESTING = TARGET
  • TESTING not defined at all

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 TESTING is not defined then it certainly doesn't equal HOST, and I do not need that extra #ifdef TESTING with the GCC compiler.

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

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


回答1:


#if TESTING==HOST

If TESTING is not defined, then

it is equivalent to:

#if 0==HOST

From the C Standard:

(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""




回答2:


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 TESTING is valid) but I think it's clearer to include them, especially when you start adding additional logic.




回答3:


The original C preprocessors required explicit #ifdef validation 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.

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



回答4:


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:

#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.




回答5:


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



来源:https://stackoverflow.com/questions/13149189/preprocessor-equality-test-is-this-standard

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!