首先面向需求,小工程、代码不多、版本还挺多...
打算用宏控制开关选项、然后通过一长串
#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_
仔细研究了下实现原理,感觉自己对宏定义的理解又深入了一个层次...其实也没有那么复杂
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
来源:oschina
链接:https://my.oschina.net/u/1000353/blog/510439