例如,如何避免两次写入'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)
例如,如何避免两次写入'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 预处理器中将值转换为字符串的基本技术确实是通过 '#' 运算符,但建议解决方案的简单音译会产生编译错误:
#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 节“# 运算符”中,它说:
类函数宏的替换列表中的每个 # 预处理标记应后跟一个参数,作为替换列表中的下一个预处理标记。
问题是您可以将宏参数转换为字符串——但您不能转换不是宏参数的随机项。
所以,要达到你想要的效果,你肯定需要做一些额外的工作。
#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);
}
我不完全清楚您计划如何使用宏,以及您计划如何完全避免重复。这个稍微复杂一点的例子可能会提供更多信息。使用与 STR_VALUE 等效的宏是获得所需结果所必需的惯用语。
#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的名字使用了“害羞”作为名字的一部分。
@Jonathan Leffler:谢谢。您的解决方案有效。
一个完整的工作示例:
/** 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
看这里