如何从Cmacros的值做一个string?

例如,如何避免两次写'func_name'?

#ifndef TEST_FUN # define TEST_FUN func_name # define TEST_FUN_NAME "func_name" #endif 

我想遵循“ 单点实施规则”。

C预处理器的版本:

 $ cpp --version cpp (GCC) 4.1.2 20070626 (Red Hat 4.1.2-14) 

害羞的人给了你一个答案的细菌,但只有细菌。 在C预处理器中将值转换为string的基本技巧实际上是通过'#'运算符,但是所提出的解决scheme的简单音译会产生编译错误:

 #define TEST_FUNC test_func #define TEST_FUNC_NAME #TEST_FUNC #include <stdio.h> int main(void) { puts(TEST_FUNC_NAME); return(0); } 

语法错误在'puts()'行 – 问题是源中的“杂散#”。

在C标准的第6.10.3.2节中,“#运营商”说:

类似函数的macros的replace列表中的每个#预处理标记后面必须有一个参数作为replace列表中的下一个预处理标记。

麻烦的是,你可以将macros参数转换为string – 但不能转换不是macros参数的随机项目。

所以,为了达到你以后的效果,你当然必须做一些额外的工作。

 #define FUNCTION_NAME(name) #name #define TEST_FUNC_NAME FUNCTION_NAME(test_func) #include <stdio.h> int main(void) { puts(TEST_FUNC_NAME); return(0); } 

我并不完全清楚你打算如何使用macros,以及你打算如何避免重复。 这个稍微详细的例子可能会提供更多的信息。 等同于STR_VALUE的macros的使用是获得期望的结果所必需的习惯用法。

 #define STR_VALUE(arg) #arg #define FUNCTION_NAME(name) STR_VALUE(name) #define TEST_FUNC test_func #define TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC) #include <stdio.h> static void TEST_FUNC(void) { printf("In function %s\n", TEST_FUNC_NAME); } int main(void) { puts(TEST_FUNC_NAME); TEST_FUNC(); return(0); } 

*在写这个答案的时候, shoosh的名字使用了“Shy”作为名字的一部分。

@Jonathan Leffler:谢谢。 你的解决scheme有效

一个完整的工作示例:

 /** compile-time dispatch $ gcc -Wall -DTEST_FUN=another_func macro_sub.c -o macro_sub && ./macro_sub */ #include <stdio.h> #define QUOTE(name) #name #define STR(macro) QUOTE(macro) #ifndef TEST_FUN # define TEST_FUN some_func #endif #define TEST_FUN_NAME STR(TEST_FUN) void some_func(void) { printf("some_func() called\n"); } void another_func(void) { printf("do something else\n"); } int main(void) { TEST_FUN(); printf("TEST_FUN_NAME=%s\n", TEST_FUN_NAME); return 0; } 

例:

 $ gcc -Wall -DTEST_FUN=another_func macro_sub.c -o macro_sub && ./macro_sub do something else TEST_FUN_NAME=another_func 
 #include <stdio.h> #define QUOTEME(x) #x #ifndef TEST_FUN # define TEST_FUN func_name # define TEST_FUN_NAME QUOTEME(TEST_FUN) #endif int main(void) { puts(TEST_FUN_NAME); return 0; } 

参考:维基百科的C预处理器页面

#define TEST_FUN_NAME #FUNC_NAME

看到这里