2011-08-30 20 views
6

Los siguientes identificadores no tienen ningún vínculo: un identificador declarado como cualquier cosa que no sea un objeto o una función; un identificador declarado como un parámetro de función; identificador de ámbito de bloque para un objeto declarado sin el especificador de clase de almacenamiento extern.Enlace del alcance del bloque C estándar

{ 
    static int a; //no linkage 
} 

Para un identificador declarado con el extern especificador de clase de almacenamiento en un ámbito en el que una declaración previa de que el identificador es visible, si la declaración previa especifica enlace interno o externo, la unión del identificador en la declaración posterior es la misma que la vinculación especificada en la declaración previa. Si no hay una declaración previa visible, o si la declaración previa no especifica ningún vínculo, , entonces el identificador tiene un enlace externo.

{ 
    static int a; //no linkage 
    extern int a; //a should get external linkage, no? 
} 

error GCC: declaración externa de una continuación de una declaración sin vinculación

Puede alguien explicar por qué me sale este error?

Gracias

+1

Podría ser la semántica, "especifica ninguna vinculación" frente a "especifica" ningún vínculo". La promoción automática en este caso suena loca. –

+0

No entiendo la diferencia. ¿Podrías elaborar? – mindless

Respuesta

8

Su suposición es correcta: la segunda declaración de a tiene un enlace externo. Sin embargo, se produce un error debido a que su código infringe una restricción en la §6.7:

3 If an identifier has no linkage, there shall be no more than one declaration of the identifier (in a declarator or type specifier) with the same scope and in the same name space, except for tags as specified in 6.7.2.3.

Es decir, una vez que haya declarado a tener ninguna vinculación, no se puede redeclare de nuevo en el mismo ámbito.


Un ejemplo válido de esta regla es que se invoque:

int a = 10; /* External linkage */ 

void foo(void) 
{ 
    int a = 5; /* No linkage */ 

    printf("%d\n", a); /* Prints 5 */ 

    { 
     extern int a; /* External linkage */ 

     printf("%d\n", a); /* Prints 10 */ 
    } 
} 
+1

¿Podría darme un ejemplo válido de: si la declaración previa no especifica ningún vínculo, entonces el identificador tiene un enlace externo. No puedo pensar en ninguno. – mindless

+0

@mindless: He agregado un ejemplo a mi respuesta. – caf

2

if the prior declaration specifies no linkage

significa

if the prior declaration specifies not a sign of linkage

y no

if the prior declaration specifies that it has no linkage

Esto es confuso y ambiguo; no es la forma habitual de escribir un estándar ...

+0

Puede eliminar estática, el error todavía estaría allí. El alcance estático en bloque no cambia el enlace, solo la duración de almacenamiento. En el alcance del archivo, cambia el enlace, pero no la duración de almacenamiento (siempre estática). Otra ambigüedad en c. – mindless

+0

Estás equivocado; el significado pretendido es el último, precisamente como está escrito. No tiene ninguna relación con la pregunta, de todos modos. – caf

Cuestiones relacionadas