如何在 C 中连接两个字符串宏?
How do I concatenate two string macros in C?
我正在尝试为我的程序实现 VERSION 宏,这将在某些情况下进行更改。
macro VERSION 是通过 Makefile 定义的(git 信息放在那里)并且是一个字符串。
现在我有一组#define'd 开关,我希望VERSION 反映它们中的哪一个是打开的。现在看起来如下 (main.h):
#define COMPLEX_DEPOSITION // This is switch. later in code it is used in #ifdef...#endif construction.
#ifdef COMPLEX_DEPOSITION
#define CD "_COMP_DEP" // this is the string I want to put in the end of VERSION
#define VERSION_ VERSION CD
#undef VERSION // this is to suppress 'macro redefinition' warning
#define VERSION VERSION_
#undef VERSION_
#endif
好吧,我遇到了很多错误,其中大部分让我认为 C 预处理器以随机顺序处理文件中的行:(
稍后我有一个更复杂的东西,旨在使 VERSION -> VERSION_WLT_GAP_2
#define WIRESLIFETIMES
#ifdef WIRESLIFETIMES
#define GAP 2
#define VERSION_ (VERSION ## "_WLT_GAP_" ## #GAP)
#define VERSION VERSION_
#undef VERSION_
#endif
我不知道该怎么做,如果这可能的话
当彼此相邻放置时,字符串文字会自然连接
"foo" "bar"
等同于 "foobar"
.
至于第二个例子,你可能想要:
#define CAT_(A,B) A##B
#define CAT(A,B) CAT_(A,B)
#define GAP 2
#define VERSION CAT(VERSION_WLT_GAP_ , GAP)
VERSION //expands to VERSION_WLT_GAP_2
我建议稍微玩一下 gcc -E
/clang -E
,以了解宏的工作原理,
在尝试用它们编写任何复杂的东西之前。
嗯,答案好像是这样的:
//
// Concatenate preprocessor tokens A and B without expanding macro definitions (however, if invoked from a macro, macro arguments are expanded).
#define PPCAT_NX(A, B) A ## B
// Concatenate preprocessor tokens A and B after macro-expanding them.
#define PPCAT(A, B) PPCAT_NX(A, B)
// Turn A into a string literal without expanding macro definitions (however, if invoked from a macro, macro arguments are expanded).
#define STRINGIZE_NX(A) #A
// Turn A into a string literal after macro-expanding it.
#define STR(A) STRINGIZE_NX(A)
#define COMPLEX_DEPOSITION
#ifdef COMPLEX_DEPOSITION
#define CD "_COMPDEP"
#else
#define CD ""
#endif
#define WIRESLIFETIMES
#ifdef WIRESLIFETIMES
#define GAP 2
#define WLT STR(PPCAT(_WLT:G, GAP))
#define DISABLE_METROPOLIS
#else
#define WLT ""
#endif
#define VERSION VERSIONX CD WLT
产生 V008.1-11-g68a9c89cb4-dirty_COMPDEP_WLT:G2
,我很满意。
必须注意我在Makefile
里面把-DVERSION=...
改成了-DVERSIONX=...
我正在尝试为我的程序实现 VERSION 宏,这将在某些情况下进行更改。
macro VERSION 是通过 Makefile 定义的(git 信息放在那里)并且是一个字符串。 现在我有一组#define'd 开关,我希望VERSION 反映它们中的哪一个是打开的。现在看起来如下 (main.h):
#define COMPLEX_DEPOSITION // This is switch. later in code it is used in #ifdef...#endif construction.
#ifdef COMPLEX_DEPOSITION
#define CD "_COMP_DEP" // this is the string I want to put in the end of VERSION
#define VERSION_ VERSION CD
#undef VERSION // this is to suppress 'macro redefinition' warning
#define VERSION VERSION_
#undef VERSION_
#endif
好吧,我遇到了很多错误,其中大部分让我认为 C 预处理器以随机顺序处理文件中的行:(
稍后我有一个更复杂的东西,旨在使 VERSION -> VERSION_WLT_GAP_2
#define WIRESLIFETIMES
#ifdef WIRESLIFETIMES
#define GAP 2
#define VERSION_ (VERSION ## "_WLT_GAP_" ## #GAP)
#define VERSION VERSION_
#undef VERSION_
#endif
我不知道该怎么做,如果这可能的话
当彼此相邻放置时,字符串文字会自然连接
"foo" "bar"
等同于 "foobar"
.
至于第二个例子,你可能想要:
#define CAT_(A,B) A##B
#define CAT(A,B) CAT_(A,B)
#define GAP 2
#define VERSION CAT(VERSION_WLT_GAP_ , GAP)
VERSION //expands to VERSION_WLT_GAP_2
我建议稍微玩一下 gcc -E
/clang -E
,以了解宏的工作原理,
在尝试用它们编写任何复杂的东西之前。
嗯,答案好像是这样的:
//
// Concatenate preprocessor tokens A and B without expanding macro definitions (however, if invoked from a macro, macro arguments are expanded).
#define PPCAT_NX(A, B) A ## B
// Concatenate preprocessor tokens A and B after macro-expanding them.
#define PPCAT(A, B) PPCAT_NX(A, B)
// Turn A into a string literal without expanding macro definitions (however, if invoked from a macro, macro arguments are expanded).
#define STRINGIZE_NX(A) #A
// Turn A into a string literal after macro-expanding it.
#define STR(A) STRINGIZE_NX(A)
#define COMPLEX_DEPOSITION
#ifdef COMPLEX_DEPOSITION
#define CD "_COMPDEP"
#else
#define CD ""
#endif
#define WIRESLIFETIMES
#ifdef WIRESLIFETIMES
#define GAP 2
#define WLT STR(PPCAT(_WLT:G, GAP))
#define DISABLE_METROPOLIS
#else
#define WLT ""
#endif
#define VERSION VERSIONX CD WLT
产生 V008.1-11-g68a9c89cb4-dirty_COMPDEP_WLT:G2
,我很满意。
必须注意我在Makefile
里面把-DVERSION=...
改成了-DVERSIONX=...