c++ - locales - lógica retorcida: una variable global en un archivo se refiere a una variable externa pero también se refiere a esa variable externa
variables globales en c (1)
fileA.cpp:
#include <iostream>
extern int iA;
extern int iB= iA;
int main()
{
std::cout<<iA<<'',''<<iB;
}
fileB.cpp
extern int iB;
extern int iA = 2*iB;
Compilado y enlazado y ejecutado, sale en el modo de depuración y liberación es 0,0
Mi pregunta es cómo funciona, ¿por qué no hay ningún problema en la etapa de vinculación? Estoy usando VC ++ 2003.
El inicializador anula la palabra clave extern
, por lo que no hay nada "mágico" en esto: simplemente declaras y defines dos variables completamente independientes en diferentes funciones.
[C++14: 3.1/2]:
una declaración es una definición a menos que declare una función sin especificar el cuerpo de la función (8.4), contiene el especificadorextern
(7.1.1) o una especificación de enlace 25 (7.5) y ni un inicializador ni un cuerpo de función , declara un miembro de datos estáticos en una definición de clase (9.2, 9.4), es una declaración de nombre de clase (9.1), es una declaración enum opaco (7.2), es un template-parameter (14.1), es una declaración de parámetro (8.3.5) en un declarador de función que no es el declarador de una definición de función , o es una declaracióntypedef
(7.1.3), una declaración de alias ( 7.1.3), una declaración de uso (7.3.3), una declaración de aserción estática (Cláusula 7), una declaración de atributo (Cláusula 7), una declaración de vacío (Cláusula 7) o una directiva de uso (7.3. 4).
Su programa es por lo tanto equivalente a lo siguiente:
fileA.cpp
#include <iostream>
extern int iA;
int iB= iA;
int main()
{
std::cout<<iA<<'',''<<iB;
}
fileB.cpp
extern int iB;
int iA = 2*iB;
Ahora, ambos objetos se someten necesariamente a la inicialización estática (a todos los ceros a nivel de bit) antes de que ocurra cualquier otra cosa. Cuando se produce la inicialización dinámica más tarde, dependiendo de si los objetos static-storage-duration en fileA.cpp o fileB.cpp se inicializan primero (y no se puede saber qué orden será) cualquiera de los iB
se inicializa a cero iA
(entonces iA
se inicializa a 2*iB
como se esperaba), o iA
se inicializa a cero iB
multiplicado por dos, que sigue siendo dos (entonces iB
se inicializa a cero iA
).
De cualquier manera, ambos objetos van a terminar, a través de una semántica bien definida, teniendo un valor de cero.