4

I'm writing a logger module, so I would like to print the debug infos like __FILE__ and __LINE__ in c/c++. So I used macro function like:

/// here's just an example
/// function str_format() returns a std::string in format like printf() in c
#define info(str, ...) (cout << str_format(str, ##__VA_ARGS__) << __FILE__ << ":" << __LINE__)

in most cases, it works fine. but 'define' just has more influence than I thought. to give an example, if a member variable in c++ class needs initialize:

class test{
private:
    int info;
public:
    test(int a) : info(a) {}
};

this would cause an unexpected error, the compiler would take info as a macro function! even the header file of logger(which is logger.h) is not included in the class test's file, as long as the third file include them both, and include 'logger.h' before 'test.h' would cause this problem! that's really annoying. So, is there any way other than #undef (since the test.h has nothing to with logger.h) to solve this problem? or let's say how can I get debug info like FILE without using macro function?

Quentin
  • 62,093
  • 7
  • 131
  • 191
陈泽霖
  • 95
  • 6

2 Answers2

3

As far as __FILE__ and __LINE__ is concerned, C++20 introduced std::source_location for this. There is no equivalent non-macro based solution in prior C++ standards.

As far as a non-macro logging solution overall, the most common approach involves implementing the logging function as a variadic template with a parameter pack, that ends up formatting the log message, from its parameters.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
0

No, there is no other way. You'll have to either not use file information (really, who cares what your file is called? Most likely you actually care about the call stack at a problem location, which is what exceptions give you) or use better names than info. In fact the convention for macros is to use all caps, like INFO.

Blindy
  • 65,249
  • 10
  • 91
  • 131