Continuando desde su comentario: "puede explicar en mayor detalle las declaraciones adelantadas" ...
declaraciones
Adelante son exactamente lo que suenan. Una declaración que se definirá en otro lugar (generalmente más adelante). Este concepto solo se aplica a símbolos globales. Solo puede haber UNA definición de símbolo global dentro de un binario resultante. Sin embargo, puede declararlos una y otra vez dentro del código fuente para que puedan ser referenciados durante la fase de compilación.
Estos símbolos se convierten en definiciones en el ensamblaje que luego se utilizan para vincular todo junto durante la fase de vinculación.
Los archivos de encabezado son ejemplos de uso común de declaraciones directas que se definen en otro lugar (más adelante) en el código.
Las variables locales (automáticas) no se convierten en símbolos. Así, cuando decimos algo así como
int x;
int x;
dentro del mismo ámbito que el compilador no lo permite, ya que no tiene sentido. Las variables locales son simplemente una conveniencia para señalar a una ubicación particular dentro del marco de pila de la función. Su límite de definición está dentro de los marcadores de alcance {
}
.
Los archivos de encabezado son esencialmente "declaraciones directas" de variables y funciones globales; para ver esto para su como en struct foo;
.
Si desea ver la definición global causar errores, intente. int x = 10;
int x = 11;
como global, y verá que el compilador escupe un error con el efecto "redifinción de x".
Estoy de acuerdo con lo que dices. Pero ¿por qué no se aplica lo mismo a las variables locales? Creo que me estoy perdiendo algo muy obvio. Señale en la dirección correcta – Bazooka
puede tener una definición tentativa solo para las variables que tienen alcance de archivo y no para las variables locales. –