перекрестная инициализация глобальных (внешних) переменных

У меня проблема с пониманием того, как компилятор/компоновщик генерирует фактический код при инициализации переменных, имеющих межфайловую область (extern). Я имею в виду, в каком порядке они создаются? Это кажется проблематичным, когда хотя бы одна из переменных определена с помощью какой-то другой... Например, это работает так, как ожидалось:

основной.cpp:

    #include <iostream>
    using namespace std;

    extern int varA;

    int varB=1;

    int main ()
     {
      cout << "varA = " << varA << endl;
      cout << "varB = " << varB << endl;
      system ("pause");
      return 0;
     }

переменнаяA.cpp

extern int varB;
int varA=varB;

ВЫВОД:

varA = 1   --> as expected!!
varB = 1   --> as expected!!

Теперь следующее, немного более сложное, дает неожиданный результат:

файл classB.h:

#ifndef H_classB
#define H_classB

class classB {
public: 
    classB();
    int varB;
};

#endif

файл classB.cpp:

#include "classB.h"

classB myB;  // defined => cross-file scope by using extern in other files

classB::classB() {
    varB=1; // constructor initialized varB to 1
}

файл classA.h:

#ifndef H_classA
#define H_classA

class classA {
public: 
    classA();
    int varA;
};

#endif

файл classA.cpp:

#include "classA.h"
#include "classB.h"

extern classB myB;

classA myA; // defined => cross-file scope by using extern in other files

classA::classA() {
    varA=myB.varB;  // constructor initialized varA to the value of the instance
                    // variable varB of the pre-instantiated object myB (defined 
                    //in classB.cpp). 
}

основной.cpp:

#include <iostream>
using namespace std;

#include "classA.h"
#include "classB.h"

extern classA myA;
extern classB myB;

int main ()
{

  cout << "myA.varA = " << myA.varA << endl;
  cout << "myB.varB = " << myB.varB << endl;

  system ("pause");
  return 0;
}

В этом случае ВЫВОД:

myA.varA = 0   --> WHY??? shouldn't it be 1? 
myB.varB = 1   --> as expected!

В чем причина такого поведения?


person alvaro    schedule 14.03.2013    source источник
comment
Да, глобалы зло.   -  person Peter Wood    schedule 14.03.2013
comment
возможный дубликат глобальный порядок инициализации C++ игнорирует зависимости?   -  person Bo Persson    schedule 14.03.2013


Ответы (1)


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

person user2116939    schedule 14.03.2013