首先面向需求,小工程、代码不多、版本还挺多...
打算用宏控制开关选项、然后通过一长串
#if
#elif
...
#endif
来控制生成版本号、而且还要根据兼容性跟细小变更做三级版本号....
所以就需要一个版本号拼接、明显,应该是编译期能做完的事情。
--------需求完毕--------
C语言宏定义应该是可完成的、在代码执行期间更加是没问题的。
虽然用string.h也可以完成拼接。
不舒服斯基...
初步查找 使用 # 和##,可以完成、进一步查找发现有个#@ 是什么鬼... 部分编译器不支持
经过初步试用# 会直接把传递进来的macro直接变成string,#@理论上是实现我需要的功能,然而并不支持
---------------神奇的分割线-------------------------
进一步查找stringize site:gcc.gnu.org
找到页面
3.4 Stringification
https://gcc.gnu.org/onlinedocs/cpp/Stringification.html
鉴于是blog,就不贴原文了,又需要的自己去看。
结论:
If you want to stringify the result of expansion of a macro argument, you have to use two levels of macros.
#define xstr(s) str(s) #define str(s) #s #define foo 4 str (foo) ==> "foo" xstr (foo) ==> xstr (4) ==> str (4) ==> "4"
结合## 无限可能出来了
#define xstr(s) str(s) //copy from https://gcc.gnu.org/onlinedocs/cpp/Stringification.html #define str(s) #s #define _STRING_(_X_) xstr(_X_) //convert from macro to string #define BSP_HARD_REVERSION 1.0.0 #define SW_FIRST_VERSION 8 #define SW_MID_VERSION 800 #define SW_LAST_VERSION 021 #define SW_FULL_VSERSION SW_FIRST_VERSION##.##SW_MID_VERSION##.##SW_LAST_VERSION #define HW_VERSION_STRING _STRING_(BSP_HARD_REVERSION) #define SW_VERSION_STRING _STRING_(SW_FULL_VSERSION) static const char hw_rev[] = HW_VERSION_STRING; //hw_rec config by boards.h static const char fw_rev[] = "8.0.0"; static const char sw_rev[] = SW_VERSION_STRING; #undef str #undef xstr #undef _STRING_
OK 到这里我需要的功能已经搞定。大家随便拿个调试工具看看就可以了,确实是OK的
仔细研究了下实现原理,感觉自己对宏定义的理解又深入了一个层次...其实也没有那么复杂
s is stringified when it is used in str, so it is not macro-expanded first. But s is an ordinary argument to xstr, so it is completely macro-expanded before xstr itself is expanded (see Argument Prescan). Therefore, by the time str gets to its argument, it has already been macro-expanded.
原文地址
http://my.oschina.net/mummy108/blog/510439