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...
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, ...) \
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__);
Top comments (0)