1

I want to implement a C/C++ variadic logging macro, which contains __FILE__ and __LINE__ information.

This is my simple implementation:

#include <stdio.h>

#define MYLOG(format, ...) printf("%s:%d " format, __VA_ARGS__)

The only issue is that, this macro doesn't compile when my logging has no parameters, for example:

MYLOG("hello world");

I've read some wikis and blogs, there's a solution for GCC compiler:

#include <stdio.h>

#define MYLOG(format, ...) printf("%s:%d " format, ##__VA_ARGS__)

But is there a more standard way to implement this macro working on GCC/Clang/MSVC compilers?

linrongbin
  • 2,967
  • 6
  • 31
  • 59
  • What about simply using 2 different macros? `#define MYLOG(text) printf("%s:%d %s", __FILE__, __LINE__, text)` ... `#define MYLOG_FMT(format, ...) printf("%s:%d " format, __FILE__, __LINE__, __VA_ARGS__)` Call `MYLOG()` when you don't have format parameters, and call `MYLOG_FMT()` when you do. – Remy Lebeau Jan 17 '20 at 05:44
  • @RemyLebeau, It really solve the issue, but I'm just looking for a killer solution. – linrongbin Jan 17 '20 at 05:52
  • 1
    Take a good look at [`#define` macro for debug printing in C](https://stackoverflow.com/q/1644868/15168) — it covers most of the territory you need, and includes passing reference to adding `__FILE__` and `__LINE__` information to the logging. – Jonathan Leffler Jan 17 '20 at 05:55
  • https://stackoverflow.com/a/8673872/918959 – Antti Haapala -- Слава Україні Jan 17 '20 at 06:25
  • 1
    Also there is no such language as C/C++. Either something is C or is not, something is C++ or not. A minority of code is in the **intersection**. What it is that you want? – Antti Haapala -- Слава Україні Jan 17 '20 at 06:27
  • You could use the [facil.io STL library logging macros (or copy them)](https://github.com/boazsegev/facil.io/blob/cef033faad21659ce20f95d910fe5c558a32ffc8/lib/facil/fio-stl.h#L698-L825) – Myst Jan 17 '20 at 07:11
  • P.S., there's [documentation as well](https://github.com/boazsegev/facil.io/blob/cef033faad21659ce20f95d910fe5c558a32ffc8/docs/_SOURCE/0.8.x/fio-stl.md#logging-and-assertions). – Myst Jan 17 '20 at 07:18

1 Answers1

2

If your compiler supports C++20 then there is a standard way to solve this problem using __VA_OPT__. __VA_OPT__(,) will expand to a comma if __VA_ARGS__ is not empty. So when __VA_ARGS__ is empty, there's no extra comma and no compilation error.

#define MYLOG(format, ...) printf("%s:%d " format __VA_OPT__(,) __VA_ARGS__)
Indiana Kernick
  • 5,041
  • 2
  • 20
  • 50