I'm trying to leverage class constructors and deconstructors to represent and format scope in my log files via the RAII idiom. Using a single #define
, it prints "{" and increases the global indentation level so that the next logged line is printed at that indentation level.
LogScopeRAII
is supposed to print the "}" and decrease the global indentation level naturally as it goes out of scope at the end of Foo()
. However, the behavior I am seeing is that LogScopeRAII is deconstructed immediately after being constructed.
Hypothesis: I think the problem is that LogScopeRAII is being created on the RHS of the assignment (and thus anonymously?) and is being destroyed at the end of the line, but I'm not sure what to do about. I thought LOG_ANONYMOUS_VARIABLE
in VSCOPE_F
would have done the trick and caused it to stick around, but it isn't.
Question: How can I stop LogScopeRAII from being deconstructed until the calling function goes out of scope?
/* Header */
LogScopeRAII::LogScopeRAII(Verbosity verbosity, const char* file, unsigned line, const char* format, ...)
{
// ...
// print "{" and then increase an indentation global var
}
LogScopeRAII::~LogScopeRAII()
{
// ...
// print "}" and then decrease the indentation global var
}
#define LOG_ANOMYMOUS_VARIABLE(str) LOG_CONCAT(str, __LINE__)
#define VSCOPE_F(verbosity, ...) \
LogScopeRAII LOG_ANONYMOUS_VARIABLE(raii) = \
((verbosity) > verb_cutoff() ? LogScopeRAII() : LogScopeRAII{verbosity, __FILE__, __LINE__, __VA_ARGS__}
#define SCOPE_F(verbosity_name, ...) VSCOPE_F(Verbosity_ ## verbosity_name, __VA_ARGS__)
#define SCOPE_FUNCTION(INFO) SCOPE_F(verbosity_name, __FUNCTION__)
/* Implementation */
void Foo()
{
SCOPE_FUNCTION(INFO) // print "{" and increase indentation
for (size_t i = 0; i < 3; ++i)
{
// do work
LOG(INFO, "Work logged");
}
// print "}" and decrease indentation
}
Desired output:
{ Foo()
"Work Logged" // Note indentation
} 0.23 s: Foo()
EDIT: BOILED THE ISSUE DOWN
The crux of it is this: The ternary doesn't seem to be working.
This works:
LogScopeRAII a(LogScopeRAII{ Verbosity_INFO, __FILE__, static_cast<unsigned>(__LINE__), "" });
But this does not:
LogScopeRAII a(((Verbosity_INFO) > indent) ? LogScopeRAII() : LogScopeRAII{ Verbosity_INFO, __FILE__, static_cast<unsigned>(__LINE__), "" });
I get:
{
}
Work logged
Work logged
Work logged
}
constructCounter: 1
destructCounter: 2
Exiting...
should be
else you use copy constructor of temporary variable.
(You might also fix you move-constructor and destructor to allow your current MACRO)