gpt4 book ai didi

c++ - 我可以依赖函数范围的静态变量来调用程序关闭期间调用的方法吗?

转载 作者:可可西里 更新时间:2023-11-01 16:36:42 27 4
gpt4 key购买 nike

快速上下文:我看到程序关闭时出现错误,这些错误源于全局成员之间的依赖关系(::sigh::,我知道,我知道)。一个全局变量的析构函数可能引用另一个全局变量——如果那个全局变量已经被破坏,事情就会变得糟糕。

但这是一个我不知道行为是否明确定义的特殊情况:函数内的静态变量。即使在程序关闭期间,我是否可以依赖函数的行为始终如一?或者是否有可能静态成员将被销毁,并且该函数将运行而不创建新成员?

这是一个玩具示例,展示了我感兴趣的内容:

class Logger
{
public:
enum class Severity { DEBUG, INFO, WARNING, ERROR };
void Log(Severity sev, const std::string& msg)
{
LogImpl(FormatMessage(sev, msg));
}

Logger() { Log(Severity::INFO, "Logger active"); }
~Logger() { Log(Severity::INFO, "Logger inactive"); }

protected:
static std::string FormatMessage(Severity sev, const std::string& msg)
{
static const std::map<Severity, std::string> enum2str {
{Severity::DEBUG, "DEBUG"},
{Severity::INFO, "INFO"},
{Severity::WARNING, "WARNING"},
{Severity::ERROR, "ERROR"}
};

// Throws or crashes if enum2str is invalid, or uninitialized:
return "[" + enum2str[sev] + "] " + msg;
}
void LogImpl(const std::string& msg)
{
std::cout << msg << std::endl;
}
};

假设我有一个Logger 的全局实例。 Logger::FormatMessage 中的 enum2str 映射是一个静态变量,因此在程序关闭期间的某个时刻,它会被销毁。

按照标准,这会导致我的程序在关机时崩溃吗? enum2str 在关机期间是否天生不可靠?或者对此有一些处理——例如,如果 enum2str 在某个时候无效,也许会创建一个新的静态实例?

(我对依赖对象之间的销毁顺序不感兴趣,例如我声明全局 Logger 实例的地方。)

最佳答案

没有看到更多你的程序,一般的答案是肯定的。该静态映射的破坏可能导致您的程序具有未定义的行为:

[basic.start.term]

3 If the completion of the constructor or dynamic initialization of an object with static storage duration strongly happens before that of another, the completion of the destructor of the second is sequenced before the initiation of the destructor of the first [...]

4 If a function contains a block-scope object of static or thread storage duration that has been destroyed and the function is called during the destruction of an object with static or thread storage duration, the program has undefined behavior if the flow of control passes through the definition of the previously destroyed block-scope object. Likewise, the behavior is undefined if the block-scope object is used indirectly (i.e., through a pointer) after its destruction.

通常,静态对象的销毁顺序与初始化顺序相反。因此假设,如果您有一个静态对象在记录器中的映射之前提前初始化,并且它在自己的析构函数中记录了一些内容,您将得到未定义的行为。

关于c++ - 我可以依赖函数范围的静态变量来调用程序关闭期间调用的方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52925392/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com