¿Por qué no hay error en este progtwig?

— ac —-

int i; // external definition 

—- C Principal ——

 int i=0; // external definition int main(void) { i=0; } 

En ambos archivos, i es una definición externa en cada unidad de traducción y i se usa en una expresión. Eso debería violar:

Si un identificador declarado con enlace externo se usa en una expresión (que no sea parte del operando de un operador sizeof cuyo resultado es una constante entera), en algún lugar del progtwig completo habrá exactamente una definición externa para el identificador; de lo contrario, no habrá más de uno.140)

Este comportamiento no estándar es una extensión común implementada en muchos comstackdores C.

Este asunto se discute de manera bastante extensa en Racionalidad al estándar C99 (vea las páginas 32-34). Y, de acuerdo con ese documento, este conjunto de definiciones sería legal bajo el modelo Ref / Def relajado que normalmente se implementa en los comstackdores C de UNIX OS de la era anterior a C89. Esta es la razón de su popularidad y es por eso que a menudo lo vemos implementado como una extensión. Se supone que simplifica el soporte de código heredado.

Sin embargo, el modelo de definición de C estándar es diferente: es una combinación del modelo de Ref / Def estricto y el modelo de Inicialización . El estándar C no permite esto.

PD: Si bien es cierto que la definición de i en ac es una definición provisional , no tiene nada que ver con el problema. Al final de la unidad de traducción que contiene, todas las definiciones tentativas de algún objeto se combinan y dan origen a una definición externa del objeto. Su naturaleza “tentativa” no es visible de ninguna manera en el nivel inter-módulo. Las definiciones provisionales no permiten crear múltiples definiciones del mismo objeto en diferentes unidades de traducción.