神奇的 ## 符号
发布日期:2021-06-28 22:05:13
浏览次数:2
分类:技术文章
本文共 3858 字,大约阅读时间需要 12 分钟。
原文链接地址:http://starryalley.homelinux.net/blog/index.php?/archives/1134-Token-Concatenation-in-C-preprocessor.html
使用程式碼來介紹比較快:
#define foo() bar foo()baz ==> bar baz not ==> barbaz 所以加上’##’的用法,就可以達成barbaz,以下是範例: #define COMMAND(NAME) { #NAME, NAME ## _command } struct command commands[] = { COMMAND (quit), COMMAND (help), //... }; #define COMMAND(NAME) { #NAME, NAME ## _command }struct command commands[] = { COMMAND (quit), COMMAND (help), //...}; 經過C preprocessor處理後,會展開如下: struct command commands[] = { { “quit”, quit_command }, { “help”, help_command }, //... }; struct command commands[] = { { “quit”, quit_command }, { “help”, help_command }, //...}; 其中#NAME是Stringification的功能,所以配合’##’ token concatenation,我們可以結合兩個param。
之前在trace ffmpeg source code,其中竟然找不到put_pixels4_c()這類 function的definition,ctags找不到,grep好久也沒有。原來就是利用了token concatenation來產生的function。
以下是 節錄ffmpeg 0.5 source 裡面的一段code,用了C preprocessor token concatenation(其中省略了不相關的幾行程式碼):
- #define PIXOP2(OPNAME, OP) /
- static void OPNAME ## _pixels2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){/
- //...
- OP(*((uint16_t*)(block)), AV_RN16(pixels));/
- //...
- }/
- static void OPNAME ## _pixels4_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){/
- //...
- OP(*((uint32_t*)(block)), AV_RN32(pixels));/
- //...
- }/
- //...
在下面則使用這段code的方式:
- #define op_avg(a, b) a = rnd_avg32(a, b)
- #define op_put(a, b) a = b
- PIXOP2(avg, op_avg)
- PIXOP2(put,op_put)
- #undef op_avg
- #undef op_put
- //from ffmpeg0.5, libavcodec/dsputil.c
使用gcc -E來展開preprocessor動作後,Line 1261和1262,呼叫PIXOP2的macro,就會自動產生新的function definition:
- static void avg_pixels2_c(uint8_t *block, const uint8_t pixels, int line_size, int h){
- ((uint16_t*)(block )) = rnd_avg32(*((uint16_t*)(block )), AV_RN16(pixels ));
- }
- static void avg_pixels4_c(uint8_t *block, const uint8_t pixels, int line_size, int h){
- ((uint32_t*)(block )) = rnd_avg32(*((uint32_t*)(block )), AV_RN32(pixels ));
- }
- static void put_pixels2_c(uint8_t *block, const uint8_t pixels, int line_size, int h){
- ((uint16_t*)(block )) = AV_RN16(pixels );
- }
- static void put_pixels4_c(uint8_t *block, const uint8_t pixels, int line_size, int h){
- ((uint32_t*)(block )) = AV_RN32(pixels );
- }
又學到一招,這code還真簡潔明瞭,不需要重複寫很多同質性的function definition。
有關C preprocessor的token concatenation介紹請參考 。
转载地址:https://blog.csdn.net/yfh1985sdq/article/details/5699838 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月24日 16时40分28秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Android中高级面试必知必会,积累总结
2019-04-29
Activity的6大难点,你会几个?跳槽薪资翻倍
2019-04-29
Android-App的设计架构经验谈,系列篇
2019-04-29
Android-Camera内存问题剖析,安卓系列学习进阶视频
2019-04-29
Android-Camera内存问题剖析,小白也能看明白
2019-04-29
Android事件分发机制及设计思路,先收藏了
2019-04-29
Android事件分发机制收藏这一篇就够了,不吃透都对不起自己
2019-04-29
Android内存泄漏总结,offer拿到手软
2019-04-29
Android内存泄漏总结,成功拿下大厂offer
2019-04-29
Android初级开发是如何一步步成为高级开发?源码+原理+手写框架
2019-04-29
最新BAT大厂面试者整理的Android面试题目模板,看看这篇文章吧!
2019-04-29
最详细的docker中安装并配置redis,好文推荐
2019-04-29
月薪20k+的Android面试都问些什么?3面直接拿到offer
2019-04-29
月薪20k+的Android面试都问些什么?深夜思考
2019-04-29
月薪20k+的Android面试都问些什么?绝对干货
2019-04-29
有了这些中高端面试专题-大厂还会远吗?工作感悟
2019-04-29
有了这些中高端面试专题-大厂还会远吗?我先收藏为敬
2019-04-29
有了这些中高端面试专题-大厂还会远吗?系列篇
2019-04-29
来看看移动端小程序技术的前世今生!讲的明明白白!
2019-04-29
来看看这份超全面的《Android面试题及解析》,大厂面经合集
2019-04-29