que estaba teniendo un problema extraño que redujo a la siguiente caso de prueba:Acceso globales estáticas en una función en línea
inl.h:
inline const char *fn() { return id; }
a.cc:
#include <stdio.h>
static const char *id = "This is A";
#include "inl.h"
void A()
{
printf("In A we get: %s\n", fn());
}
b.cc:
#include <stdio.h>
static const char *id = "This is B";
#include "inl.h"
void B()
{
printf("In B we get: %s\n", fn());
}
extern void A();
int main()
{
A();
B();
return 0;
}
Ahora cuando compilo esto con g++ -O1 a.cc b.cc
parece que funciona correctamente. Me sale:
In A we get: This is A
In B we get: This is B
pero si compilo con g++ -O0 a.cc b.cc
me sale:
In A we get: This is A
In B we get: This is A
Tenga en cuenta que en realidad estoy tratando de utilizar la semántica C11 aquí, pero estoy usando g ++ como gcc no lo hace soporte C11 todavía.
Ahora, hasta donde puedo ver, mirando tanto la especificación C11 como la especificación C++ (las especificaciones C++ 11 y anteriores - la semántica de las variables globales en línea y estáticas no parece haber cambiado), debería hacer lo que quiero, y la falla al usar -O0
es un error en gcc.
¿Es esto correcto, o hay algo en algún lugar de la especificación que me falta que haría este comportamiento indefinido?
Editar
La respuesta común parece afirmar que fn
necesidades a ser declarados como static
para que esto funcione. Pero de acuerdo con 6.7.4.6 de la especificación C99 (6.7.4.7 en la especificación C11 - no está seguro acerca de la especificación C++):
Si todas las declaraciones ámbito de archivo para una función en una unidad de traducción incluyen la especificador de función en línea sin extern, entonces la definición en esa unidad de traducción es una definición en línea. Una definición en línea no proporciona una definición externa para la función, y no prohíbe una definición externa en otra unidad de traducción.
Así que como no hay explícito extern
aquí, estas deberían ser dos funciones en línea independientes sin interacción entre ellas. No se requiere static
explícito.
El uso de una static explícita soluciona el problema de C, pero no funciona para las funciones de miembro en línea de C++, ya que la palabra clave static
tiene un significado completamente diferente en ese caso.
Fuera de interés, ¿se replica el comportamiento si reemplaza las inclusiones con la definición de función en línea? Si el preprocesador se está ejecutando como primer pase independiente como me imagino, debería poder simplificar el caso de prueba. –
Por cierto: ¿qué versión de gcc? –
gcc 4.5.3 y 4.6.1 ambos se comportan de esta manera. –