连接预处理器定义以形成字符串
Concatenate preprocessor defines to form a string
我有这个:
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define REVISION b
#define VERSION VERSION_MAJOR.VERSION_MINOR REVISION
#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)
integer version_major = VERSION_MAJOR;
integer version_minor = VERSION_MINOR;
string revision = STRINGIFY(REVISION);
string version_string = STRINGIFY(VERSION);
但是,这会将 version_string
设置为 "1.0 b"
。我想消除 VERSION_MINOR 和 REVISION 之间的 space。我试过这个:
#define VERSION VERSION_MAJOR.VERSION_MINOR##REVISION
但它产生 "1.VERSION_MINORREVISION"
。显然,这也行不通:
#define VERSION VERSION_MAJOR.VERSION_MINORREVISION
是否可以连接两个预处理器值而中间没有 space?
更新: 我更改了语言,因为问题是关于预处理器而不是关于语言。我实际上需要它用于 LSL,尽管我最初用 C 语法来表述问题,这对更多用户来说是熟悉的,但 LSL 不允许通过使它们相邻来形成更长的字符串文字。
经过深挖,我发现确实可以,方法如下。
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define REVISION b
#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)
/* here's the magic */
#define _CONCAT(x,y) x##y
#define CONCAT(x,y) _CONCAT(x,y)
#define VERSION VERSION_MAJOR.CONCAT(VERSION_MINOR,REVISION)
integer version_major = VERSION_MAJOR;
integer version_minor = VERSION_MINOR;
string revision = STRINGIFY(REVISION);
string version_string = STRINGIFY(VERSION);
和STRINGIFY
一样,宏CONCAT
需要定义两层才能生效。
输出为:
integer version_major = 1;
integer version_minor = 0;
string revision = "b";
string version_string = "1.0b";
符合预期。
在 C 语言中,两个相邻的字符串被视为一个字符串并自动连接起来。因此,如果您有 "abc" "def"
,这与 "abcdef"
相同。同样,如果您有 A 和 B 的宏,那么 #A #B
会将它们连接起来。
例如,此代码应生成您要查找的 version_string:
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define REVISION b
#define STRINGIFY(x) #x
#define VERSION_STR(A,B,C) STRINGIFY(A) "." STRINGIFY(B) STRINGIFY(C)
char *version_string = VERSION_STR(VERSION_MAJOR, VERSION_MINOR, REVISION);
我有这个:
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define REVISION b
#define VERSION VERSION_MAJOR.VERSION_MINOR REVISION
#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)
integer version_major = VERSION_MAJOR;
integer version_minor = VERSION_MINOR;
string revision = STRINGIFY(REVISION);
string version_string = STRINGIFY(VERSION);
但是,这会将 version_string
设置为 "1.0 b"
。我想消除 VERSION_MINOR 和 REVISION 之间的 space。我试过这个:
#define VERSION VERSION_MAJOR.VERSION_MINOR##REVISION
但它产生 "1.VERSION_MINORREVISION"
。显然,这也行不通:
#define VERSION VERSION_MAJOR.VERSION_MINORREVISION
是否可以连接两个预处理器值而中间没有 space?
更新: 我更改了语言,因为问题是关于预处理器而不是关于语言。我实际上需要它用于 LSL,尽管我最初用 C 语法来表述问题,这对更多用户来说是熟悉的,但 LSL 不允许通过使它们相邻来形成更长的字符串文字。
经过深挖,我发现确实可以,方法如下。
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define REVISION b
#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)
/* here's the magic */
#define _CONCAT(x,y) x##y
#define CONCAT(x,y) _CONCAT(x,y)
#define VERSION VERSION_MAJOR.CONCAT(VERSION_MINOR,REVISION)
integer version_major = VERSION_MAJOR;
integer version_minor = VERSION_MINOR;
string revision = STRINGIFY(REVISION);
string version_string = STRINGIFY(VERSION);
和STRINGIFY
一样,宏CONCAT
需要定义两层才能生效。
输出为:
integer version_major = 1;
integer version_minor = 0;
string revision = "b";
string version_string = "1.0b";
符合预期。
在 C 语言中,两个相邻的字符串被视为一个字符串并自动连接起来。因此,如果您有 "abc" "def"
,这与 "abcdef"
相同。同样,如果您有 A 和 B 的宏,那么 #A #B
会将它们连接起来。
例如,此代码应生成您要查找的 version_string:
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define REVISION b
#define STRINGIFY(x) #x
#define VERSION_STR(A,B,C) STRINGIFY(A) "." STRINGIFY(B) STRINGIFY(C)
char *version_string = VERSION_STR(VERSION_MAJOR, VERSION_MINOR, REVISION);