Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.03.2015, 05:24   #1
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию Порядок инициализации глобальных переменных

Здравствуйте.
1.cpp:
Код:
struct S1
{
    int i;
    S1(): i{43} {}
}s1;
2.cpp:
Код:

extern S1 s1;
struct S2
{
    int i2;
    S2(): i2 {s1.i}  {}
}s2;
Обе структуры в глобальном пространстве. Если S1 никак не использует S2, то есть ли гарантия того, что в конструкторе S2 находится должным образом инициализированная s1? Думаю да, но хотелось бы уточнить.
220Volt вне форума Ответить с цитированием
Старый 10.03.2015, 07:01   #2
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию

В общем проверил опытным путём:
g++ 1.cpp 2.cpp
S2::i2 == 43

g++ 2.cpp 1.cpp
S2::i2 == 0
никаких гарантий.
220Volt вне форума Ответить с цитированием
Старый 10.03.2015, 07:23   #3
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию

Интересный, на мой взгляд, случай нашёл http://stackoverflow.com/questions/2...lization-order:
2.cpp
Код:
using namespace std;

class A
{
public:
    static std::string myString;
    A();
};

std::string A::myString = "test";

A::A()
{
    myString += "1";
}
1.cpp
Код:
class A
{
public:
    static std::string myString;
    A();
};
A a1;

int main()
{
    cout << a1.myString;
}
g++ 2.cpp 1.cpp
программа падает.
g++ 1.cpp 2.cpp
выдаёт test1

Причины понятны, просто я к тому, что надо быть осторожней.

Последний раз редактировалось 220Volt; 10.03.2015 в 07:28.
220Volt вне форума Ответить с цитированием
Старый 10.03.2015, 07:32   #4
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Мне всегда было интересно: зачем писать корявый код, чтобы потом думать как он будет воспринят компилятором и надеяться, что в следующей версии компилятора его поведение не изменится? Не проще писать нормальный код и не задумываться о таких вещах?
pu4koff вне форума Ответить с цитированием
Старый 10.03.2015, 07:39   #5
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию

Я бы с удовольствием писал всё правильно, но я ведь не могу проштудировать весь стандарт. Учусь потихоньку. Плюс, для русскоговорящих порог повыше будет.
220Volt вне форума Ответить с цитированием
Старый 10.03.2015, 13:19   #6
ОлегС
 
Регистрация: 26.02.2015
Сообщений: 6
По умолчанию

в VS 2010 подобных проблем не возникает
ОлегС вне форума Ответить с цитированием
Старый 10.03.2015, 16:19   #7
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от 220Volt Посмотреть сообщение
Я бы с удовольствием писал всё правильно, но я ведь не могу проштудировать весь стандарт. Учусь потихоньку. Плюс, для русскоговорящих порог повыше будет.
локальные статические переменные не зависят от порядка инициализации единиц трансляций.


Код:
struct example
{
    //иммунитет к static initialization order fiasco

    //можно вызывать в любое время, в любом месте
    // стандарт гарантирует, 
    //что статическая локальная переменная 
    //будет проинициализирована только один раз,
    //при первом вызове её функции-хозяина
    //время жизни локального статика -
    //до конца работы программы
    static int& Get() { static int v=33; return v; }
};

...

// в другой ед. трансляции
struct some
{
    some() : v( example::Get()  )

    // статический член инициализируется
    // за счет другого статического члена
    // однако за счет статических-локальных переменных
    // такая инициализация не зависит 
    //от порядка инициализаций единиц трансляции, 
    //и потому безопасна
    static some& Get() { static some s; return s; }
};

...
с++11 инициализация локальной статической переменной является thread-safe
(инициализация безопасна в многопоточном среде).

Последний раз редактировалось _Bers; 10.03.2015 в 16:22.
_Bers вне форума Ответить с цитированием
Старый 10.03.2015, 16:22   #8
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от ОлегС Посмотреть сообщение
в VS 2010 подобных проблем не возникает
все там возникает.
_Bers вне форума Ответить с цитированием
Старый 10.03.2015, 22:30   #9
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию

Для полноты:
Без опасений можно объявлять глобальные constexpr переменные и static constexpr
Код:
constexpr int i = 12;   // ok

stuct S
{
    int val;
    constexpr S(): val{32} {}
};

struct Data
{
    static constexpr S s;   // ok
}
Т.к. все расчёты на этапе компиляции, то порядок строго задан #include'ами.
220Volt вне форума Ответить с цитированием
Старый 11.03.2015, 17:29   #10
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию

Я чуть-чуть не по теме:
Чего-то я въехать не могу, что происходит?
Код:
#include <iostream>
using namespace std;

struct S
{
    S()     { std::cout << "S::const\n"; }
    ~S()    { std::cout << "S::destr\n"; }
};

struct Cont
{
    const S &s;
    Cont(const S &s): s{s}  {cout << "Cont::const\n";}
    ~Cont()                 {cout << "Cont::destr\n";}
};

int main()
{
    Cont c{ S{} };
}
S::const
Cont::const
S:: destr
S:: destr
Cont:: destr

Это на mingw, clang и gcc выдают иной результат.
220Volt вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
порядок вызова конструкторов глобальных объектов через границы единиц трансляции rrrFer Общие вопросы C/C++ 10 06.09.2014 21:52
Обнуление глобальных переменных g11112 Общие вопросы Delphi 2 05.08.2013 16:35
два вопроса о глобальных переменных Ksardas13 Общие вопросы C/C++ 15 08.09.2012 10:31
Конфликт глобальных переменных RRt C/C++ Сетевое программирование 3 23.08.2012 22:51
Обнуление глобальных переменных в VBA Arkasha69 Microsoft Office Excel 1 06.09.2010 15:06