videos how hashtags c compilation fortran static-analysis c99

how - Definiciones provisionales en C99 y enlaces



how to put hashtags on youtube videos (3)

Esto es para aclarar mi respuesta a un comentario de olovb:

salida de nm para un archivo objeto compilado de "int x;" En esta plataforma, los símbolos se anteponen con un ''_'', es decir, la variable x aparece como _x.

00000000 T _main U _unknown 00000004 C _x U dyld_stub_binding_helper

salida de nm para un archivo objeto compilado de "int x = 1;"

00000000 T _main U _unknown 000000a0 D _x U dyld_stub_binding_helper

salida de nm para un archivo objeto compilado de "int x = 0;"

00000000 T _main U _unknown 000000a0 D _x U dyld_stub_binding_helper

salida de nm para un archivo objeto compilado de "extern int x;"

00000000 T _main U _unknown U dyld_stub_binding_helper

EDITAR: salida de nm para un archivo objeto compilado de "extern int x;" donde x realmente se usa en una de las funciones

00000000 T _main U _unknown U _x U dyld_stub_binding_helper

Considere el programa C compuesto por dos archivos,

f1.c:

int x;

f2.c:

int x=2;

Mi lectura del párrafo 6.9.2 de la norma C99 es que este programa debe ser rechazado. En mi interpretación de 6.9.2, la variable x se define tentativamente en f1.c , pero esta definición provisional se convierte en una definición real al final de la unidad de traducción, y (en mi opinión), por lo tanto, debería comportarse como si f1.c contuviera la definición int x=0; .

Con todos los compiladores (y, sobre todo, los vinculadores) pude probar, esto no es lo que sucede. Todas las plataformas de compilación que intenté vincularon los dos archivos anteriores, y el valor de x es 2 en ambos archivos.

Dudo que esto ocurra por accidente, o simplemente como una característica "fácil" de proporcionar además de lo que exige el estándar. Si lo piensas, significa que hay un soporte especial en el enlazador para aquellas variables globales que no tienen un inicializador, a diferencia de aquellas inicializadas explícitamente a cero. Alguien me dijo que la función del enlazador puede ser necesaria para compilar Fortran de todos modos. Esa sería una explicación razonable.

¿Alguna idea sobre esto? Otras interpretaciones del estándar? ¿Nombres de plataformas en las que los archivos f1.c y f2.c niegan a estar vinculados?

Nota: esto es importante porque la pregunta ocurre en el contexto del análisis estático. Si los dos archivos pueden negarse a vincularse en alguna plataforma, el analizador debería presentar una queja, pero si cada plataforma de compilación lo acepta, entonces no hay ninguna razón para advertirlo.


Hay algo que se llama una "extensión común" para el estándar, donde se permite la definición de variables varias veces siempre que la variable se inicialice solo una vez. Ver http://c-faq.com/decl/decldef.html

La página enlazada dice que esto es pertinente para las plataformas Unix, supongo que es lo mismo para c99 que c89, aunque tal vez haya sido adoptado por más compiladores para formar una especie de estándar de facto. Interesante.


Ver también Qué son las variables externas en C. Esto se menciona en el estándar C en el anexo J informativo como una extensión común:

J.5.11 Múltiples definiciones externas

Puede haber más de una definición externa para el identificador de un objeto, con o sin el uso explícito de la palabra clave extern; si las definiciones no están de acuerdo, o se inicializa más de una, el comportamiento no está definido (6.9.2).

Advertencia

Como @litb señala aquí, y como se afirma en mi respuesta a la pregunta de referencias cruzadas, el uso de definiciones múltiples para una variable global conduce a un comportamiento indefinido, que es la forma estándar de decir "cualquier cosa podría suceder". Una de las cosas que puede suceder es que el programa se comporte como espera; y J.5.11 dice, aproximadamente, "usted puede ser afortunado con más frecuencia de lo que se merece". Pero un programa que se basa en múltiples definiciones de una variable externa, con o sin la palabra clave explícita ''extern'', no es un programa estrictamente conformismo y no se garantiza que funcione en todas partes. Equivalentemente: contiene un error que puede o no mostrarse.