防止在宏中定义的匿名变量的解构,直到范围结束

Preventing deconstruction of anonymous variable defined in macro until end of scope

本文关键字:结束 范围 变量 定义      更新时间:2023-10-16

我正在尝试通过RAII IDIOM在日志文件中代表和格式化类构造函数和解构器。使用单个#define,它打印" {"并增加了全局压痕级别,以便在该压痕级别打印下一个记录线。

LogScopeRAII应该在Foo()的末尾自然地打印"}",并自然降低全局压痕级别。但是,我看到的行为是logscoperaii在构造后立即被解构。

假设:我认为问题是在分配的RHS上创建了LogScoperaii(因此是匿名的?),并且在行结尾被销毁,但我不是当然该怎么办。我以为VSCOPE_F中的LOG_ANONYMOUS_VARIABLE会做到这一点并导致它坚持下去,但不是。

问题:如何停止logScoperaii被解构直到调用功能范围范围范围?

/* 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
}

所需的输出:

{ Foo()
    "Work Logged" // Note indentation
} 0.23 s: Foo()

编辑:将问题归为

它的症结在于:三元式似乎不起作用。

这有效:

LogScopeRAII a(LogScopeRAII{ Verbosity_INFO, __FILE__, static_cast<unsigned>(__LINE__), "" });

但这不是:

LogScopeRAII a(((Verbosity_INFO) > indent) ? LogScopeRAII() : LogScopeRAII{ Verbosity_INFO, __FILE__, static_cast<unsigned>(__LINE__), "" });

我得到:

{
}
Work logged
Work logged
Work logged
}
constructCounter: 1
destructCounter: 2
Exiting...
#define VSCOPE_F(verbosity, ...) 
LogScopeRAII LOG_ANONYMOUS_VARIABLE(raii) = 
((verbosity) > verb_cutoff() ? LogScopeRAII() : LogScopeRAII{verbosity, __FILE__, __LINE__, __VA_ARGS__}

应该是

#define VSCOPE_F(verbosity, ...) 
LogScopeRAII LOG_ANONYMOUS_VARIABLE(raii) 
(((verbosity) > verb_cutoff() ? LogScopeRAII() : LogScopeRAII{verbosity, __FILE__, __LINE__, __VA_ARGS__})

否则,您使用临时变量的复制构造函数。

(您也可能会修复移动构造者和驱动器以允许您当前的宏)