C中macro的Token Pasting的问题

gangyewei 2016-04-21 05:12:14
我的代码如下
#define TTP_ROUTE_TABLE_ENTRY_INC(table)    \
static inline void \
ttp_route_##table_inc(void) \
{ \
cur_l3_##table_table_entries++; \
}
TTP_ROUTE_TABLE_ENTRY_INC(ipv4_host)
TTP_ROUTE_TABLE_ENTRY_INC(ipv4_route)
TTP_ROUTE_TABLE_ENTRY_INC(ipv6_host)
TTP_ROUTE_TABLE_ENTRY_INC(ipv6_route)
#undef TTP_ROUTE_TABLE_ENTRY_INC

但是GCC告警:
lib/ttp-route-table.c:130:1: error: redefinition of 'ttp_route_table_inc'

所以我认为GCC将##table翻译成table了, 而实际上我是需要:
TTP_ROUTE_TABLE_ENTRY_INC(ipv4_host)

翻译成:
static inline void  \
ttp_route_ipv4_host_inc(void) \
{ \
cur_l3_ipv4_host_table_entries++; \
}

所以请问大家要如何修改呀?
...全文
135 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
mLee79 2016-04-21
  • 打赏
  • 举报
回复
cur_l3_ ## table ## _table_entries++; \
chehw_1 2016-04-21
  • 打赏
  • 举报
回复

#define CURL_I3_TABLE_ENTRIES(table, entries) curl_I3_##table##entries

#define TTP_ROUTE_TABLE_ENTRY(table, tag)    \
static inline void  \
ttp_route_##table##tag(void)   \
{   \
  CURL_I3_TABLE_ENTRIES(table, _entries)++; \
}

#define TTP_ROUTE_TABLE_ENTRY_INC(table) TTP_ROUTE_TABLE_ENTRY(table, _inc)

TTP_ROUTE_TABLE_ENTRY_INC(ipv4_host)


pengzhixi 2016-04-21
  • 打赏
  • 举报
回复
你那样会把taken_inc解析成一个标识符那就与你的taken无关了
pengzhixi 2016-04-21
  • 打赏
  • 举报
回复
#define TTP_ROUTE_TABLE_ENTRY_INC(table)    \
static inline void  \
ttp_route_##table(void)   \
{   \
    cout<<#table<<endl;   \
}
去掉_inc
赵4老师 2016-04-21
  • 打赏
  • 举报
回复
仅供参考: #与##在宏定义中的--宏展开 #include <stdio.h> #define f(a,b) a##b #define g(a) #a #define h(a) g(a) int main() { printf("%s\n", h(f(1,2))); // 12 printf("%s\n", g(f(1,2))); // f(1,2) return 0; } 宏展开时: 如果宏定义以#开头,不展开参数,直接替换。 故g(f(1,2))--->#f(1,2)--->"f(1,2)"; 如果宏定义不以#开头,展开参数,直接替换,由外层向里层,如果碰到的是#开头的宏,不继续往里层展开,往外层展开。 由外层向里层,如果碰到的是以非#开头的宏,继续往里层走,直至最里层,开始一层层往外层展开。 故h(f(1,2))--->h(12)--->g(12)---->#12----->"12"。 PS: ##在宏中定义,是字符连接符 如a##b##c 等同于 "abc" #在宏开头出现,是表示宏展开的方式不同 #a 等同于"a" #abc 等同于 "abc" 复杂的: #include <stdio.h> #define f(a,b) a##b #define g(a) #a #define h(a) g(a) int main() { char a = 'a'; cout<<g(a)<<endl; // a cout<<g(g(a))<<endl; // a printf("%s\n", h(f(1,2))); // 12 printf("%s\n", g(f(1,2))); // f(1,2) printf("%s\n", g(h(f(1,2)))); // h(f(1,2)) printf("%s\n", h(g(f(1,2)))); // "f(1,2)" printf("%s\n", h(h(f(1,2)))); // "12" system("pause"); return 0; } 预处理后的:(在编译选项中添加/EP /P后编译生成的.i文件。gcc加-E) int main() { char a = 'a'; cout<<"a"<<endl; cout<<"g(a)"<<endl; printf("%s\n", "12"); printf("%s\n", "f(1,2)"); printf("%s\n", "h(f(1,2))"); printf("%s\n", "\"f(1,2)\""); printf("%s\n", "\"12\""); system("pause"); return 0; } --------------------------------------------------- 宏解析 1. ##操作符 ##操作符它的作用是在替代表中将其前后的参数连接成为一个预处理符号,它不能出现于宏替代表的开端和末尾。 例: #define concat(s,t) s##t #define AAA ABC concat(A, AA) 将被替换成 ABC 2. 重新扫描和替换 在替换列表中的所有参数替换过之后,预处理器将对结果token序列重新扫描以便对其中的宏再次替换。 当正在替换的宏在其替换列表中发现自身时,就不再对其进行替换。在任何正在嵌套替换的宏的替换过程中遇到正被替换的宏就对其不再进行替换(防止递归)。 例: #define ROOT AAA CCC #define AAA ROOT ROOT 将被替换成 ROOT CCC

69,374

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧