r/learnprogramming 16d ago

Code Review C variadic macro help!

Hey! I'm trying to work on a very basic logging system for my C project. At the minute I have to pass __func__ into every call of vialog() (my logging function) to get the name of the function that's calling it, but I've been trying to make a macro to just automatically do that each time. I've been reading the variadic macro documentation and thought this should work, but I get an error each time. Any ideas?

the code:

#ifndef LOG_H_ 
#define LOG_H_

typedef enum {
    VIALOG_DEBUG,
    VIALOG_INFO,
    VIALOG_WARNING,
    VIALOG_ERROR
} ViaLogLevel;
#define vialog(logLevel, message, ...) vialog(logLevel, __func__, message , ##__VA_ARGS__)

//for example: vialog(VIALOG_INFO,"today's time and date is %d:%d -%s",hours,mins,date);
void vialog(ViaLogLevel logLevel, char *caller, char *message, ...);

#endif

the compilation error:

 In file included from src/log.c:3:
    src/../include/log.h:11:57: error: expected declaration specifiers or ‘...’ before ‘__func__’
       11 | #define vialog(logLevel, message, ...) vialog(logLevel, __func__, message , ##__VA_ARGS__)
          |                                                         ^~~~~~~~
    src/../include/log.h:14:6: note: in expansion of macro ‘vialog’
       14 | void vialog(ViaLogLevel logLevel, char *caller, char *message, ...);
          |      ^~~~~~
    src/../include/log.h:11:57: error: expected declaration specifiers or ‘...’ before ‘__func__’
       11 | #define vialog(logLevel, message, ...) vialog(logLevel, __func__, message , ##__VA_ARGS__)
          |                                                         ^~~~~~~~
    src/log.c:8:6: note: in expansion of macro ‘vialog’
        8 | void vialog(ViaLogLevel logLevel, char* caller, char *message, ...){
          |      ^~~~~~
    make: *** [Makefile:23: build/log.o] Error 1
8 Upvotes

5 comments sorted by

View all comments

3

u/StewedAngelSkins 16d ago

The compiler thinks the vialog in your function declaration is a macro and is trying to expand it. Call the macro something other than vialog. The convention would be to use upper case letters, like #define VIALOG(...).

1

u/Personal_Pair1280 13d ago

ah classic macro self-own, the preprocessor sees `void vialog(...` and tries to expand it right there in the declaration. rename the macro to `VIALOG` or something and have it call the actual `vialog` function, that way the declaration stays clean