C预处理器: Is there any way to expand the name of a macro inside itself

标签 c c-preprocessor

我想要一个宏来打印它自己的名字(除其他外),但我找不到在宏本身中扩展宏名称的方法。基本上,我想要相当于 __FUNCTION__ 的宏名称。

例如:

#define F(a, b, c) do { \
   printf("%s: %s,%s,%s\n", __MACRO__, #a, #b, #c); \
   c = a+b; b=a; \
} while(0)

F(x,y,z); 

我希望它在调用时打印“F: x,y,z”。


这确实是一个 XY 问题。

我真正想做的是:使用 dlopen 和 dlsyms 从库中软链接(soft link)符号。

为了做到这一点,我知道的典型方法是: 1)包括库中的标题。 2)声明一个你试图导入的函数类型的变量 3) 通过调用 dlsym 初始化所述变量 4) 通过该变量调用实际函数而不是直接调用符号。

当你有很多这样的软链接(soft link)函数时,它会变得非常重复,所以宏可以提供帮助。

有关完整的示例,请参见此处:https://github.com/WebKit/webkit/blob/master/Source/WebCore/platform/mac/SoftLinking.h

该示例和其他示例中的问题是您仍然需要为每个要软链接(soft link)的函数手动复制参数列表。 我正在尝试对此进行改进,并且正在尝试使用宏技巧,其中之一可以通过能够回答我最初的问题得到帮助。

--

除了我的软链接(soft link)问题,在其他情况下这可能会有用。例如,出于调试目的,可能希望在每次调用某些函数之前或之后打印一些诊断信息。可以通过用宏覆盖函数名称来做到这一点:

#define funcA(...) \
printf("Before call to %s:%d - %d\n", #funcA, __LINE__, g_count); \
funcA(__VA_ARGS__) \
printf("After call to %s:%d - %d\n", #funcA, __LINE__, g_count);

这很好用,但如果我想为一堆函数执行此操作,我必须复制该宏并将每个新宏的 funcA 更改为 funcB 4 次。我宁愿复制它并只更改宏的名称,而不必更改其中的内容。

我可以通过定义一个内部宏 p 来优化上面的内容,类似于 Basile 的建议:

#define funcA(...) WRAP(funcA, __VA_ARGS__)

但这仍然意味着我每次为另一个函数复制宏时都需要将 funcA 更改为新函数名称两次。

最佳答案

阅读更多关于 C preprocessor 的信息.阅读 GNU cpp 的文档.注意它的 stringificationconcatenation能力。

也许通过一些额外的内部宏可能会对你有所帮助,所以你可能有一个像这样的公共(public)宏

 #define FOO(X,Y,Z) PRIVATE_FOO(FOO,X,Y,Z)

用另一个 PRIVATE_FOO 宏在它的第一个参数上做字符串化技巧,也许

#define PRIVATE_FOO(Mac,X,Y,Z) do { \
 printf("%s: %s,%s,%s\n", #Mac, #X, #Y, #Z); \
 Z = X+Y; Y=X; \
} while(0)

也许 C 预处理器不足以完成您的任务。你可以用一些其他工具生成一些 C 代码(可能是 GPP 预处理器,或者可能是一个简单的 awkpython 脚本,或者可能是一些真实的程序;你会需要更改您的构建过程,例如您的 Makefile,来处理它)。您可以自定义您的 GCC编译器 MELT如果你需要的话。由于我们不知道您的实际动机,因此我们无能为力。

除非您提出并澄清您的问题,否则我无能为力。

您的软链接(soft link)问题只需要使用一些 weak symbols .它可能与 C 预处理无关。

关于C预处理器: Is there any way to expand the name of a macro inside itself,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35238736/

相关文章:

c - 两者的区别定义?

c - 如何使用单独的进程但不 fork 地读取/写入 Linux 伪终端?

计算 ARM Cortex-a8 BeagleBone Black 上的时钟周期计数

c - 一种基于另一个变量对某个值执行 MPI 全部缩减的有效方法?

对结构进行操作的函数的约定

c++ - 带宏的模板函数 - 在 vector 上累积

c - Eclipse CDT-转到 #define 语句中的下一行

c - 使用宏 "Higher Order Function"生成器在 C 中进行函数式编程

c++ - Visual Studio 预处理器仅在设置了/P 时才有效

c++ - 比较客户端和远程服务器中文件列表的有效方法是什么