如何从可变长度函数创建宏?其中宏值是另一个可变长度函数

时间:2019-12-26 10:56:11

标签: c function macros

我正在尝试创建一个日志功能,该功能将打印文件名,函数名,行号和错误消息。

是否有一种方法可以为小型函数创建宏,该函数仅采用日志类型,msg和宏值将添加 FILE func LINE < / strong>,然后调用实际功能

可能是这样的:

#define func(int type,const char *msg, ...) \
        func(int type,char *__FILE__,char *__func__,char *__LINE__,const *msg,...)

1 个答案:

答案 0 :(得分:3)

如果要创建在调用期间替换或添加某些参数的宏,则不必将其编写为原型,但是由于C预处理程序是简单的文本替换处理器,因此您可以将其写为调用本身。

因此您的宏定义变为:

#define func(type, msg, ...) \
        func(type, __FILE__, __func__, __LINE__, msg, __VA_ARGS__)

C预处理器将从省略号(...)开始,将符号序列(包括冒号)分配给符号__VA_ARGS__

现在使用宏,如下例所示:

func(MYTYPE, "Info function called with stack: '%s' size %ld", bIsPrivilegedStack(stack) ? "Privileged" : "User", StackSize);

将翻译为:

func(MYTYPE, __FILE__, __func__, __LINE__, "Infofunction called with stack: '%s' size %ld", bIsPrivilegedStack(stack) ? "Privileged" : "User", StackSize);

函数原型不在宏中,应该只写一次,最好包含在头文件中,并在任何调用之前出现在编译过程中。它将包含所有参数类型,如:

void func(int type, char *__FILE__, char *__func__, int _LINE__, const *msg, ...);

注意:预处理器符号__LINE__被定义为int,而不是char *

您的文件布局将会或多或少:

//Prototype
void func(int type, char * file, char *fnc, int line, const *msg, ...);
//Macro definition
#define func(type, msg, ...) \
        func(type, __FILE__, __func__, __LINE__, msg, __VA_ARGS__)

//Usage
void foo(void)
{
    .....
    func(MYTYPE, "Info function called with stack: '%s' size %ld", bIsPrivilegedStack(stack) ? "Privileged" : "User", StackSize);
    .....
}