1

Рассмотрим следующую программу: (см видеодемонстрацию here.)C++ инициализация области видимости пространства имен переменной

#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 в качестве вывода.

+2

'Похоже, что переменная d2 инициализирована статически? И «d2», и «m» инициализируются до нуля при загрузке программы. Затем 'd2' инициализируется из' m' (который все еще равен 0). Наконец, 'm' инициализируется из' fun() '. –

+1

Почему? Вы печатаете 'd2', а не' m'. Если у вас есть 'int x = 0; int y = x; x = 42; ', вы ожидаете, что' y' также будет ретроактивно установлен на 42? –

+0

[Этот ответ] (http://stackoverflow.com/a/22117407/1413133) будет полезен. –

ответ

3

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

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

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

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

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

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

1

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

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

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

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

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

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

+0

@PravasiMeet: Нет, я не могу доказать отрицательный результат. Вместо этого, почему бы вам не объяснить, почему этот простой ответ «все еще не так» и почему вы «не согласны»? –

+0

@PravasiMeet: Либо вы _didn't_, либо вы раньше лгали о том, что в первую очередь заперли. У этого ответа был только один, и он все еще там. –

+1

@Pravasi: Правильно, еще одно доказательство того, что вы не удалили свой нисходящий поток, в отличие от вашего требования. Полный лжи сегодня :( –