简体   繁体   中英

C macros using enum

I am trying to use #if macros by defining the type of operation to invoke the right code, So i made a very simple example similar to what I am trying to do:

#include <stdio.h>

enum{ADD,SUB,MUL};

#define operation   ADD

int main()
{
   int a = 4;
   int b = 2;
   int c;

   #if (operation == ADD)
      c = a+b;
   #endif

   #if (operation == SUB)
      c = a-b;
   #endif

   #if (operation == MUL)
      c = a*b;
   #endif


   printf("result = %i",c);
   return 0;
}

But unfortunately that does not work I get the following result = 8 ... if I replace The operation with numbers it works fine .... But i want it to work as it is described above.

Any help

The preprocessor is a step that is (in a way) done before the actual compiler sees the code. Therefore it has no idea about enumerations or their values, as they are set during compilation which happens after preprocessing.

You simply can't use preprocessor conditional compilation using enumerations.

The preprocessor will always consider that as false:

#if IDENT == IDENT

It can only test for numeric values.

Simplify your code and feed it to the preprocessor:

enum {ADD,SUB,MUL};

#define operation   ADD

int main()
{
    (operation == ADD);  
}

The result of the preprocessor output is:

enum {ADD,SUB,MUL};
int main()
{
    (ADD == ADD);    
}

As you see, the enumerate value hasn't been evaluated. In the #if statement, that expression is just seen as false .

So a workaround would be to replace your enumerate by a series of #define :

#define ADD 1
#define SUB 2
#define MUL 3

like this it works. Output of preprocessor output is now:

int main()
{
   int a = 4;
   int b = 2;
   int c;


      c = a+b;
# 28 "test.c"
   printf("result = %i",c);
   return 0;
}

the solution is:

  • either rely at 100% on the preprocessor (as the solution above suggests)
  • or rely at 100% on the compiler (use enums and real if statements)

As others have said, the preprocessor performs its transformations at a very early phase in compilation, before enum values are known. So you can't do this test in #if .

However, you can just use an ordinary if statement. Any decent compiler with optimization enabled will detect that you're comparing constants, perform the tests at compile time, and throw out the code that will never be executed. So you'll get the same result that you were trying to achieve with #if .

But i want it to work as it is described above.

You seem to mean that you want the preprocessor to recognize the enum constants as such, and to evaluate the == expressions in that light. I'm afraid you're out of luck.

The preprocessor knows nothing about enums. It operates on a mostly-raw stream of tokens and whitespace. When it evaluates a directive such as

#if (operation == SUB)

it first performs macro expansion to produce

#if (ADD == SUB)

. Then it must somehow convert the tokens ADD and SUB to numbers, but, again, it knows nothing about enums or the C significance of the preceding code. Its rule for interpreting such symbols as numbers is simple: it replaces each with 0. The result is that all three preprocessor conditionals in your code will always evaluate to true.

If you want the preprocessor to do this then you need to define the symbols to the preprocessor. Since you're not otherwise using the enum, you might as well just replace it altogether with

#define ADD 1
#define SUB 2
#define MUL 3

If you want the enum, too, then just use different symbols with the preprocessor than you use for the enum constants. You can use the same or different values, as you like, because never the twain shall meet.

另一种解决方案是在包含的头文件中包含枚举。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM