3 回答
TA贡献1825条经验 获得超6个赞
他谁是害羞*给你的胚芽答案,但只有胚芽。在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()'行上-问题是源中的'stray#'。
在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的名称使用“ Shy”作为名称的一部分。
TA贡献1951条经验 获得超3个赞
一个完整的工作示例:
/** 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
TA贡献2051条经验 获得超10个赞
#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;
}
参考:Wikipedia的C预处理程序页面
- 3 回答
- 0 关注
- 548 浏览
添加回答
举报