If in a 'logger.h' file I have this:
template <int CompileTimeVerbosity>
struct Logger
{
static inline int compileTimeVerbosity = CompileTimeVerbosity;
void log(const std::string& msg) { }
};
#define LOG(logger, msgVerbosity, msg) \
if constexpr (msgVerbosity >= logger.compileTimeVerbosity) \
{ \
logger.log(msg); \
} \
inline Logger<4> loggerObj;
I include this header in a bunch of .cpp files. Then in one of them I do:
void func()
{
LOG(loggerObj, 2, std::string("Sorry, you called a ") + std::to_string(int()) + " on a " + std::to_string(int()))
}
Because the inline Logger<4> loggerObj is instructed to be defined only once and we include the header in multiple .cpp files, we don't know where it has been defined. We only know that the compiler defines it once in 'some' .cpp. Therefore when we call func() in some .cpp the 'loggerObj' identifier is probably akin to something like 'extern Logger<4> loggerObj;'. If this is the case, am I right in saying that the compiler doesn't have its full definition at that point? Also that would mean that the everything in the func() function will be compiled, and then only the linker can do the if constexpr statement against the object that's probably defined in another translation unit.
I'm not sure if this is a link-time optimization, but what's in the LOG() macro invocation should be easily optimized out by the linker, right? In other words the code generated shouldn't contain std::string() + std::string() etc.?
Unreal Engine has logging system similar to this but I think it may work completely at the macro level, so in macro invocation UELog(category, verbosity, msg) I think the entire line is just elided by the preprocessor instead of copying something like if constexpr.
Is there a way I can do this? I can't find the source code for this part of the logging system.