Краткий контекст: я вижу ошибки при завершении работы программы, которые происходят из-за зависимостей между глобальными членами ( :: 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
.Карта enum2str
в Logger::FormatMessage
является статической переменной, поэтому в какой-то момент во время завершения работы программы она будет уничтожена.
По стандартному это может вызвать сбой моей программы при завершении работы? Не является ли enum2str
ненадежным по своей природе во время выключения?Или есть некоторая обработка этого - например, если enum2str
недействителен в какой-то момент, возможно, будет создан новый статический экземпляр?
(я не заинтересован в том, чтобы полагаться на порядок уничтожения между объектами,например, где я объявляю глобальный Logger
экземпляр.)