【问题标题】:How do I concatenate two string macros in C?如何在 C 中连接两个字符串宏?
【发布时间】:2019-11-06 04:32:39
【问题描述】:

我正在尝试为我的程序实现 VERSION 宏,这将在某些情况下进行更改。

macro VERSION 是通过 Makefile 定义的(git info 放在那里)并且是一个字符串。 现在我有一组#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

我不知道该怎么做,如果这可能的话

【问题讨论】:

  • 我怀疑最简单的解决方案是#else #define CD ""- 始终连接相同的宏,但如果不需要,只需将它们定义为空字符串。
  • @SirJoBlack 谢谢,我已经看到了这个问题,它的解决方案对我不起作用。
  • @MSalters 谢谢,这解决了第一个问题,但没有解决第二个问题
  • 第二个例子的问题似乎是循环逻辑。 VERSION_ 是根据 VERSIONVERSION is then defined as VERSION_` 定义的。我什至不明白那里的真正意图。

标签: c macros concatenation preprocessor


【解决方案1】:

字符串字面量在相邻放置时自然连接

"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,以了解宏的工作原理, 在尝试用它们组合任何复杂的东西之前。

【讨论】:

  • 谢谢,但重点是 VERSION 宏包含来自 Makefile 的值
  • @Xtotdam 有条件地 (#if) #undef 那么呢?我不是建议你让它变得这么简单。我只是介绍你可以使用的核心技术。
【解决方案2】:

嗯,答案似乎是这样的:

// https://stackoverflow.com/questions/5256313/c-c-macro-string-concatenation
// 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=...

【讨论】:

    猜你喜欢
    • 2011-01-12
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 2010-12-16
    • 2011-07-12
    • 2023-03-27
    • 1970-01-01
    相关资源
    最近更新 更多