I faced a problem while implementing the logger.
First, I used to LINE and FILE with standard C Macro function like below
// global.h
..
namespace MyLogger {
class Logger
{
..
void _write(int _level, const char* _file, int _line, const char* _fmt, ...);
};
static Logger logger;
}; // namespace MyLogger
..
// avoid conflict..
#undef error
#undef trace
#define error(_MESSAGE_, ...) _write(LOG_LEVEL_ERROR, (const char*)__FILE__, (int)__LINE__, (const char*)_MESSAGE_, ##__VA_ARGS__)
#define info(_MESSAGE_, ...) _write(LOG_LEVEL_INFO, (const char*)__FILE__, (int)__LINE__, (const char*)_MESSAGE_, ##__VA_ARGS__)
#define trace(_MESSAGE_, ...) _write(LOG_LEVEL_TRACE, (const char*)__FILE__, (int)__LINE__, (const char*)_MESSAGE_, ##__VA_ARGS__)
..
// main.cpp
using namespace MyLogger;
// using like this
logger.error("- log error");
logger.info("- log info %s", "test 1");
..
In fact, it seems to work well. However, the problem occurred while using openv.
error and trace seem to conflicted with error and trace in opencv .
error: expected primary-expression before 'int' [build] CV_EXPORTS CV_NORETURN void error(int _code, const String& _err, const char* _func, const char* _file, int _line);
So I'm thinking about other methods using inline functions, not macros.
// global.h
..
//void _write(int _level, const char* _file, int _line, const char* _fmt, ...);
static inline void error(/* Is it possible to toss __LINE__ or __FILE__ ? */);
static inline void info(/* .. */);
static inline void trace(/* .. */);
..
// main.cpp
logger::error("- log error");
logger::info("%d %c %f, 1, 'A', '0.1');
Can I know the line or file of the location where the log was output through a method other than a macro?
No , inline
functions/methods won't work the same as macro in this context. Macros are simply text replacement, so the __LINE__
and __FILE__
will give accurate results. So macros are your only choice ; see if you can name them better to avoid conflicts.
However the inline
functions are systematically compiled subunits. So the line number and the file names will always be same that of those functions where it resides.
There are 3 stages in which C++ becomes a running program.
__LINE__
and __FILE__
are processed by the preprocessor (stage 1). However, it's the compiler that decides about inlining (stage 2).
Other languages like C# have this in the compiler stage: [CallerMemberName]
, [CallerFilePath]
and [CallerLineNumber]
[MSDN] but I am don't think this exists in C++ at the moment.
How about this:
#define log_error(_MESSAGE_, ...) \
logger._write( \
LOG_LEVEL_ERROR, \
(const char*)__FILE__, \
(int)__LINE__, \
(const char*)_MESSAGE_, \
##__VA_ARGS__)
There is no much difference between logger.error
and log_error
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.