С++ инициализация переменной области видимости пространства имен

Рассмотрим следующую программу: (см. живую демонстрацию здесь.)

#include <iostream>
inline double fun()
{
    return 3.0;
}
extern double m;
double d2=m;
int main()
{
    std::cout<<d2;
}
double m=fun();

Я ожидал получить вывод программы как 3.0, но он дает мне вывод 0. Почему?

Похоже, что переменная d2 инициализируется статически?

Разве он не должен быть инициализирован динамически?

Я тестировал его на g++ 4.8.1, 4.9.2 и MSVS 2010 и получил 0 в качестве вывода.


person Destructor    schedule 27.09.2015    source источник
comment
It looks like variable d2 is initialized statically? Вроде того. И d2, и m первым делом инициализируются 0 при загрузке программы. Затем d2 инициализируется из m (которое по-прежнему равно 0). Наконец, m инициализируется из fun().   -  person Igor Tandetnik    schedule 27.09.2015
comment
Почему это? Вы печатаете d2, а не m. Если у вас есть int x = 0; int y = x; x = 42;, вы ожидаете, что y также будет задним числом установлено на 42?   -  person Igor Tandetnik    schedule 27.09.2015
comment
Этот ответ будет полезен.   -  person Manos Nikolaidis    schedule 27.09.2015


Ответы (2)


Переменные в файле C++ инициализируются сверху вниз. Итак, m инициализируется после d.

Есть и другие тонкости.

Когда компилятор может это обработать, он иногда выдает определения данных для переменных, устанавливая значение известной константы. Это происходит до загрузки программы.

Тогда порядок инициализации - это сегменты кода - как конструкторы. Эти сегменты располагаются сверху вниз в единице компиляции.

В вашем случае d=m думаю копирует значение из слота для m. Который установлен на 0.0

Затем вызывается m=fun(), копируя слот с правильным значением.

person mksteve    schedule 27.09.2015

Да, и d2, и m имеют статическую продолжительность хранения, потому что они объявлены без оформления в области пространства имен.

Это означает, что они нулевыми инициализируются в качестве первого шага, прежде чем произойдет любая другая инициализация. Затем d2 устанавливается на m. Только после этого m становится 3.0.

Рассмотрим следующее, что по сути одно и то же:

int main()
{
   int x = 0, y = 0;
   y = x;
   x = 3;
}

Понятно, что здесь бессмысленно ожидать, что y будет равно 3, но это то, что вы делаете.

Если вы ожидали, что инициализация произойдет, как для переменных function-static, где инициализация происходит при первом использовании (вроде), вы ошиблись.

person Lightness Races in Orbit    schedule 27.09.2015
comment
@PravasiMeet: Нет, я не могу доказать обратное. Вместо этого, почему бы вам не объяснить, почему этот простой ответ по-прежнему неверен и почему вы с ним не согласны? - person Lightness Races in Orbit; 27.09.2015
comment
@PravasiMeet: Либо вы не сделали, либо вы солгали ранее о том, что проголосовали против. Этот ответ когда-либо был только один, и он все еще там. - person Lightness Races in Orbit; 27.09.2015
comment
@Pravasi: Правильно, еще одно доказательство того, что вы не удалили свой отрицательный голос, вопреки вашему утверждению. Сегодня полно лжи :( - person Lightness Races in Orbit; 27.09.2015