If you want create a macro that during invocation replaces or adds some parameters, you don't have to write it as a prototype, but, because C preprocessor is a simple text replacement processor, you can write it as the invocation itself.
So your macro definition becomes:
#define func(type, msg, ...) \
func(type, __FILE__, __func__, __LINE__, msg, __VA_ARGS__)
The C preprocessor assign to the symbol __VA_ARGS__
the sequence of parameters, included the colon, that starts from elipsis (...) on.
Now using the macro as in the example below:
func(MYTYPE, "Info function called with stack: '%s' size %ld", bIsPrivilegedStack(stack) ? "Privileged" : "User", StackSize);
Will translate in:
func(MYTYPE, __FILE__, __func__, __LINE__, "Infofunction called with stack: '%s' size %ld", bIsPrivilegedStack(stack) ? "Privileged" : "User", StackSize);
The function prototype isn't in the macro and should be write once only, preferably contained in an header file, and appear in the compiling process before any invocation. It will contain all parameters types as in:
void func(int type, char *__FILE__, char *__func__, int _LINE__, const *msg, ...);
Note: the preprocessor symbol __LINE__
is defined as an int
, not a char *
.
Your file layout will be more or less:
//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);
.....
}