c ++宏的一个问题是扩展

时间:2013-09-10 03:52:36

标签: c++ c macros

当我使用g ++编译cpp文件时,gcc会给出以下错误消息:

  

错误:粘贴“TBSYS_LOG_LEVEL_”和“ - ”不提供有效的预处理令牌

然后我检查源代码,发现有三个宏定义:

  • fileA.h
#define TBSYS_LOG_LEVEL_ERROR 0
#define TBSYS_LOG(level, _fmt_, args...) ((TBSYS_LOG_LEVEL_##level>TBSYS_LOGGER._level) ? (void)0 : TBSYS_LOG_BASE(level, "[%ld] " _fmt_, pthread_self(), ##args))
  • fileB.h
#define ERROR -1

事实证明,在“TBSYS_LOG”扩展之前,“ERROR”扩展为“-1”。

展开“ TBSYS_LOG_LEVEL _ ## level ”之后的结果是“ TBSYS_LOG_LEVEL_-1 ”,最后导致错误消息。

但是,据我所知,宏在这种情况下不会扩展。 (使用##时)

然后我写了另一个cpp文件试试这个:

#define FOOBAR 100
#define TEST(PARAM) FOO##PARAM
#define BAR -1

int main(){
    cout<<TEST(BAR)<<endl; 
}

这可以通过编译。输出为100。 这些宏定义与前者相同,但不会将“BAR”扩展为“-1”,不会导致错误消息。

有人知道为什么宏会在前一种情况下扩展吗?


更新:使用TBSYS_LOG的代码是:

  

TBSYS_LOG(ERROR, "expand data buffer failed, length: %d", bufsize);

2 个答案:

答案 0 :(得分:0)

#define FOOBAR 100
#define TEST(PARAM) FOO##PARAM
#define BAR -1

int main(){
    cout<<TEST(BAR)<<endl; 
}

##PARAM表示符号本身。因此TEST(BAR)扩展为FOO##BAR(不是结果,只是为了解释),FOOBAR#define FOOBAR 100为100。

BAR永远不会作为独立符号出现(由空格或其他分隔符分隔),因此不能替换为-1。

答案 1 :(得分:0)

FOO ## PARAM将在编译时展开,因此在运行代码之前,宏的值已经修复,它是FOOBAR,如果你 像这样添加一个新的参数:

#define FOOBAR 100
#define TEST(PARAM) FOO##PARAM
#define BAR -1
#define GOOD 10

int main(){
    cout<<TEST(GOOD)<<endl; 
}

编译器可能永远不会让它适合你。