繁体   English   中英

gcc 预处理器变量到字符串文字

[英]gcc preprocessor variables to string literals

我知道有无数这样的问题,但我找不到好的答案。 我正在使用 CFLAGS 中定义的预处理器标记编译源代码:

-DX=字符串 1 -DY=字符串 2

我正在尝试在我的 header 文件中创建一个字符串文字,它结合了这两个值并在我的源代码中使用它,例如:

printf("%s", COMBINED);

但这不起作用:

 #define _COMBINED(x, y) x ## y
 #define COMBINED _COMBINED(X, Y)

谢谢

你没有展示你如何调用编译器的例子,所以我做了一些实验。 由于逗号(和其他非字母数字字符)会妨碍,归结为需要传递引号作为宏替换文本的分隔符。

所以我认为你真正的问题是如何以等效的方式传递字符串:

#define X "hello, "
#define Y "world!"

注意:由于逗号和感叹号,这里特别困难。

如果包含引号的宏替换文本被传递,则 C 源代码变得简单。 在 C 中,您无需任何中间运算符即可连接字符串。 "abc" "def""abcdef"相同。

#include <stdio.h>

#define COMBINED X Y

int main(void) {
    printf("%s\n", COMBINED);
}

根据您的实际用例,您甚至可以将其简化为:

#include <stdio.h>

int main(void) {
    printf("%s\n", X Y);
}

在 Bash 中,您需要像这样转义命令行 arguments,例如:

gcc -Wall -pedantic -D 'X="hello, "' -D 'Y="world!"' combine.c -s -O3 -o combine

在 Windows 的 CMD 中,您可以像这样转义引号,例如:

gcc -Wall -pedantic -D "X=\"hello, \"" -D "Y=\"world!\"" combine.c -s -O3 -o combine.exe

要将字符串化标记传递给串联宏,您需要一个间接级别。 这意味着您将它传递给不同的宏。

#define COMBINED(a, b) (a##b)
#define COMBINE(a, b) COMBINED(a, b)

然后你传递 COMBINE 中的参数,在你的情况下,X 和 Y

int main (void)  // best practice is to void-erize non-param-ed functions
{
    printf("%s\n", COMBINE(X,Y));
}

如果你真的想“直接”做,你可以这样做:

#define DEFAULT_COMBINE COMBINE(X,Y)

并致电:

printf("%s\n", DEFAULT_COMBINE);

现在,让我们以一个警告结束,因为这也是关于“最佳实践”的,所以它非常重要,尽管对您来说可能不是那样,但相信我。 从来没有,我的意思是永远不要用下划线开始你自己的预处理器定义或常量。 从来没有,在任何情况下。 即使你的兄弟在微软工作或在 Linux kernel 上工作。

在标准和最佳实践 C 和 C++ 世界中,_COMBINED 宏是非法的。 不,不是无效,这只是意味着你不应该那样命名。 简短的版本是以下划线开头的常量、内部变量和宏是编译器或内部的。 知道它不是某人设置的东西是一个“标记”。

更新:

要将它们连接起来而不是字符串,您还需要一个中间步骤来进行字符串化:

#define COMBINED(x1, x2)        x1##x2
#define COMBINE_STRINGS(x1, x2) COMBINED(#x1,#x2)
#define COMBINE(x1, x2)         COMBINE_STRINGS(x1, x2)

-DX=string1创建类似于#define X string1的预处理器标记。 到目前为止,还没有什么能使它成为字符串文字,您需要在类似函数的宏中使用# "stringinizing" 运算符才能做到这一点。

此外,在处理字符串文字时,无需使用带有##的标记连接,因为在彼此之后键入两个字符串文字意味着它们会被预处理器连接起来。

###一样,应用它们的任何宏参数都需要在使用运算符之前提前展开,因为这些运算符总是在标记替换之前应用。 所以我们不能这样做:

#define STRCAT(x,y) #x #y
#define COMBINED STRCAT(X,Y)
// bad: result will BE "XY"

而是使用额外的辅助宏:

#define STR(x) #x
#define STRCAT(x,y) STR(x) STR(y)
#define COMBINED STRCAT(X,Y)
// good: result will be "string1string2"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM