简体   繁体   English

使用枚举的 C 宏

[英]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:我试图通过定义操作类型来使用 #if 宏来调用正确的代码,所以我做了一个非常简单的例子,类似于我想要做的:

#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.但不幸的是,这不起作用我得到以下result = 8 ...如果我用数字替换操作它工作正常......但我希望它像上面描述的那样工作。

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.如您所见,尚未评估 enumerate 值。 In the #if statement, that expression is just seen as false .#if语句中,该表达式仅被视为false

So a workaround would be to replace your enumerate by a series of #define :因此,一种解决方法是将您的枚举替换为一系列#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)要么 100% 依赖预处理器(如上面的解决方案所示)
  • or rely at 100% on the compiler (use enums and real if statements)或者 100% 依赖编译器(使用枚举和真实的if语句)

As others have said, the preprocessor performs its transformations at a very early phase in compilation, before enum values are known.正如其他人所说,在enum值已知之前,预处理器在编译的早期阶段执行其转换。 So you can't do this test in #if .所以你不能在#if做这个测试。

However, you can just use an ordinary if statement.但是,您可以只使用普通的if语句。 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 .因此,您将获得与尝试使用#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.然后它必须以某种方式将标记ADDSUB转换为数字,但同样,它对枚举或前面代码的 C 意义一无所知。 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.将此类符号解释为数字的规则很简单:将每个符号都替换为 0。结果是代码中的所有三个预处理器条件将始终评估为真。

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.您可以根据需要使用相同或不同的值,因为这两个值永远不会相遇。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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