programacion manejo lenguaje lectura escritura ejercicios binarios ats archivos c standards compilation iso

manejo - Por qué una variable no se puede definir dos veces en 2 archivos en C



manejo de archivos en c++ fstream (1)

¿Por qué no puedo tener int a; en 2 archivos C. Tengo la intención de combinar ambos para hacer ejecutable. Sé por experiencia que no puedo, pero quiero encontrar dónde dice esto el estándar C99 y sellar mi comprensión.

Estoy leyendo la norma ISO C99 de http://www.open-std.org/jtc1/sc22/wg...docs/n1256.pdf . Dice en la página 42:

6.2.2 Vínculos de identificadores

1 Un identi fi cador declarado en diferentes ámbitos o en el mismo ámbito más de una vez puede referirse al mismo objeto o función mediante un proceso llamado vinculación. Hay tres tipos de vinculación: externa, interna y ninguna.

2 En el conjunto de unidades de traducción y bibliotecas que constituye un programa completo, cada declaración de un identi fi cador particular con enlace externo denota el mismo objeto o función. Dentro de una unidad de traducción, cada declaración de un identi fi cador con enlace interno denota el mismo objeto o función. Cada declaración de un identi fi cador sin vínculo denota una entidad única.

3 Si la declaración de un identi fi cador de alcance de archivo para un objeto o una función contiene el especi fi cador estático de la clase de almacenamiento, el identi fi cador tiene un enlace interno.

4 Para un identi fi cador declarado con el especi fi cador de clase de almacenamiento externo en un ámbito en el cual una declaración previa de ese identi fi cador es visible, si la declaración anterior especifica un enlace interno o externo, el enlace del identi fi cador en la declaración posterior es el mismo que el Enlace especi fi cado en la declaración anterior. Si no hay una declaración previa visible, o si la declaración anterior no especifica ningún enlace, entonces el identi fi cador tiene un enlace externo.

5 Si la declaración de un identi fi cador para una función no tiene un especi fi cador de clase de almacenamiento, su vinculación se determina exactamente como si se declarara con el especi fi cador externo de la clase de almacenamiento. Si la declaración de un identi fi cador para un objeto tiene alcance de archivo y no tiene almacenamiento -Especificador de clase, su vinculación es externa.

Después de leer esto, parece que si declaro una variable como, por ejemplo, int a; en 2 archivos de origen. luego ambos tienen vínculos externos según las reglas 5 y 4. y luego según la regla 2, ambos deben referirse al mismo objeto. Entonces, ¿por qué el compilador crea problema? Donde en la norma se insinúa que no podemos declarar así en 2 archivos de origen y esto debería arrojar un error de compilación. Primero, donde en la norma, dice que int a es una definición, y luego donde dice que 2 instancias de definiciones no son aceptables. Sé que no está permitido desde mi experiencia, pero sería muy útil para mí si pudiera encontrar esto en la norma y sellar mi comprensión.

¿Los siguientes extractos de la norma en combinación equivalen a esta regla? o me he perdido ese pegamento? :

Una declaración especifica la interpretación y los atributos de un conjunto de identificadores. Una de fi nición de un identi fi cador es una declaración para ese identi fi cador que: - para un objeto, hace que el almacenamiento se reserve para ese objeto; —Para una función, incluye el cuerpo de la función; —Para una constante de enumeración o un nombre typedef, es la (única) declaración del identi fi cador.

Como se discutió en 5.1.1.1, la unidad de texto del programa después del preprocesamiento es una unidad de traducción, que consiste en una secuencia de declaraciones externas. Estos se describen como "externos" porque aparecen fuera de cualquier función (y, por lo tanto, tienen un alcance de archivo). Como se explica en 6.7, una declaración que también hace que el almacenamiento se reserve para un objeto o una función nombrada por el identi fi cador es una de fi nición.

Una de fi nición externa es una declaración externa que también es una de fi nición de una función (que no sea una de fi nición en línea) o un objeto. Si un identi fi cador declarado con enlace externo se usa en una expresión (que no sea parte del operando de un operador de tamaño de cuyo resultado es una constante entera), en algún lugar del programa completo habrá una definición externa para el identi fi cador; De lo contrario, no habrá más de uno.

Gracias.


Creo que necesitas 6.9.2 / 2:

Una declaración de un identificador para un objeto que tiene alcance de archivo sin un inicializador y sin un especificador de clase de almacenamiento o con el static especificador de clase de almacenamiento constituye una definición provisional . Si una unidad de traducción contiene una o más definiciones tentativas para un identificador, y la unidad de traducción no contiene una definición externa para ese identificador, entonces el comportamiento es exactamente como si la unidad de traducción contiene una declaración de alcance de archivo de ese identificador, con el tipo compuesto como del final de la unidad de traducción, con un inicializador igual a 0.

y 6.9 / 5:

Una definición externa es una declaración externa que también es una definición de una función (que no sea una definición en línea) o un objeto. Si un identificador declarado con enlace externo se usa en una expresión (aparte de como parte del operando de un operador sizeof cuyo resultado es una constante entera), en algún lugar del programa completo habrá exactamente una definición externa para el identificador; De lo contrario, no habrá más de uno.

Básicamente, int a; Es una definición tentativa . Puede tener múltiples definiciones tentativas en una sola unidad de traducción, pero el efecto es el mismo que tener una definición externa no tentativa (por ejemplo, algo como int a = 0; ). Tener más de una definición de un objeto con enlace externo en un programa es una violación de 6.9 / 5.

Tenga en cuenta que se trata de una "extensión común" para permitir más de una definición externa de un objeto siempre que, como máximo, solo se inicialice una y coincidan las definiciones (consulte J.5.11).