Порядок инициализации статических переменных
От: Посторонним В. Беларусь  
Дата: 11.12.13 10:28
Оценка:
Есть такой код

a.h
...
namespace X
{
    const std::string Foo = "foo";
    inline std::string getFoo()
    {
        return Foo;
    }
}
...


a.cpp:
#include "a.h"
...
namespace X
{
   const string Default_Foo = getFoo();
}
...


Само-собой в проекте есть еще файлы, который инклудят a.h

На старте программа валится в segfault в выделенной строчке. Исследование показало, что:

1. в программе создается несколько копий Foo
-bash-4.2# nm -oC a.out | grep Foo
/usr/local/bin/RESEPT/www/authmod.fcgi:3c162c50 b X::Foo
/usr/local/bin/RESEPT/www/authmod.fcgi:3c162990 b X::Foo
/usr/local/bin/RESEPT/www/authmod.fcgi:3c1641b0 b X::Foo


2. В процессе инициализации Default_Foo вызывается getFoo(), которая берет не уже инициализированую Foo из единицы компиляции a.cpp (как я бы ожидал), а Foo из другой единицы компиляции, в которой, волею судеб, Foo еще не инициализирована.
Что приводит в segfault-у.

Кто-нибудь может объяснить, верно ли такое поведение?
Как лучше всего избегать такого рода ошибок?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.