【问题标题】:Preprocessor symbol in library and change the symbols value while using the library库中的预处理器符号并在使用库时更改符号值
【发布时间】:2019-11-20 13:08:01
【问题描述】:

我的Lib.h 中有一个带有内联函数的库项目:

 static inline void DoStuff(void) __attribute__ ((always_inline));
 static inline void DoStuff(void)
 {
 #if(SYMBOL == 1)
     // Stuff
 #elif(SYMBOL == 2)
     // Other stuff   
 #endif
}

我将我的库编译成libLib.a 并设置SYMBOL=2。现在我在其他项目中使用这个库和标题Lib.h。本项目设置SYMBOL=1,并在本项目中调用DoStuff()#if 指令的哪一部分被执行?我假设编译器将使用#if(SYMBOL == 1) 运行该部分,但我不确定。编译器是怎么处理的?

【问题讨论】:

  • library into libLib.a and set SYMBOL=2 - 你是怎么做到的?你如何“设置”“SYMBOL=2”?显示代码。

标签: c gcc


【解决方案1】:

首先,预处理器指令的正确语法是:

static inline void DoStuff(void) __attribute__ ((always_inline));
static inline void DoStuff(void)
{
#if SYMBOL == 1
    // Stuff

#elif SYMBOL == 2
    // Other stuff   

#endif
}

如果您愿意,您也可以在比较周围留下括号,但这并不是像常规 if 条件那样绝对必要。

如果您不确定哪些代码部分处于活动状态,您可以使用#warning 使其一目了然:

#if SYMBOL == 1
 #warning Symbol == 1
    // Stuff

#elif SYMBOL == 2
 #warning Symbol == 2
    // Other stuff  

#endif

【讨论】:

  • 好吧,#error 编译会失败,所以#warning 是更好的选择。如果不支持,编译器也会报错,所以和#error不支持的效果几乎一样;)
  • #warning 在我的情况下确实有效,所以我已经验证了我的假设。
  • 带括号的语法没有错,只是不需要。
  • @thebusybee 我没有声称,但其他部分是错误的(否则,endif 缺失)
  • 是的,但这让我眼前一亮。对不起,噪音。无论如何,您可能想扩展您的答案。 ;-)
【解决方案2】:

在 C 中,以 # 开头的行由预处理器预处理,这意味着当你编译它时,编译器会这样读取它(例如,如果 in库 SYMBOL=1:

static inline void DoStuff(void) __attribute__ ((always_inline));
static inline void DoStuff(void)
{
    //only the stuff that were in the block of SYMBOL=1
}

当您将代码编译到库中时,它不再知道 SYMBOL。 当您在代码中更改 SYMBOL 时,它只会针对该项目进行更改。 要解决此问题,请在标头中使用宏:

在 DoStuff.h 中:

void __do_stuff1();
void __do_stuff2();
static inline void DoStuff()
{
    #if SYMBOL==1
        __do_stuff1();
    #elif SYMBOL==2
        __do_stuff2();
    #endif
}

在 DoStuff.c 中:

void__do_stuff1(){...}
void __do_stuff2(){...}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-17
    • 2023-03-12
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    • 2021-01-17
    相关资源
    最近更新 更多