DEV Community

Juan Burgos
Juan Burgos

Posted on • Updated on

Micro-Post: Simple Logging PreProcessor Macro

Was chatting with a university student I'm mentoring and she mentioned she's going to take a C Programming course in the Fall semester and was asking for advice.

Among the various advice I gave her, I included this macro:

$ cat logger.h
// Preprocessor Macro: https://en.cppreference.com/w/c/preprocessor/replace
#define LOG(msg, ...) { \
  printf("File %s | Line %d :: ", __FILE__, __LINE__); \
  printf((msg), ##__VA_ARGS__); \
}

$ cat -n test-logger.cc
     1  #include <stdio.h>
     2  #include "logger.h"
     3
     4  int main() {
     5    LOG("%s %s!\n", "HELLO", "WORLD");
     6    bool check = true;
     7    if (check) {
     8      LOG("[ERROR] Some condition has been fulfilled that shouldn't have! Check what happened...\n");
     9    }
    10    return 0;
    11  }

$ cc test-logger.cc -o test-logger && ./test-logger
File test-logger.cc | Line 5 :: HELLO WORLD!
File test-logger.cc | Line 8 :: [ERROR] Some condition has been fulfilled that shouldn't have! Check what happened...
Enter fullscreen mode Exit fullscreen mode

Bit of a contrived example, but it should hopefully illustrate the macro's potential.

Really wish I knew this macro, and other useful ones, when I was taking my C/C++ intro courses back in the day. Would have been a great tool in my "debug my own code" toolset to replace the famous printf("I HAVE REACHED LINE XYZ IN MY CODE") style of debugging with hardcoded line numbers :D

-- Addendum --
If you want to use these macros in a C++ program, you may need to add --std=c++11 or higher along with -Wno-gnu-zero-variadic-macro-arguments to avoid errors such as:

error: variadic macros are a C99 feature [-Werror,-Wvariadic-macros]
#define LOG_INFO(msg, ...) \
Enter fullscreen mode Exit fullscreen mode

and:

error: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Werror,-Wgnu-zero-variadic-macro-arguments]
  fprintf(stderr, "File %s | Line %d :: (ERROR) ", __FILE__, __LINE__); fprintf(stderr, (msg), ##__VA_ARGS__);
Enter fullscreen mode Exit fullscreen mode

Top comments (0)