0

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

错误:粘贴“TBSYS_LOG_LEVEL_”和“-”没有给出有效的预处理令牌

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

  • 文件A.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))
  • 文件 B.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);

4

2 回答 2

0

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

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

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

编译器可能永远不会让它为你工作。

于 2013-09-10T08:40:38.433 回答
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。

于 2013-09-10T03:58:10.620 回答