2011-08-30 15 views
6

I seguenti identificativi non hanno alcun collegamento: un identificatore dichiarato come qualcosa di diverso da un oggetto o una funzione; un identificatore dichiarato come parametro di funzione; un identificatore di ambito di blocco per un oggetto dichiarato senza l'identificatore di classe di memoria extern.Collegamento oscilloscopio C standard

{ 
    static int a; //no linkage 
} 

Per un identificatore dichiarato con la classe di archiviazione specificatore extern in un ambito in cui una previa dichiarazione di tale identificatore è visibile, se la dichiarazione preventiva specifica collegamento interno o esterno, il legame tra l'identificatore in la dichiarazione successiva è la stessa del collegamento specificato nella dichiarazione precedente. Se non è visibile alcuna dichiarazione precedente, o se la dichiarazione precedente non specifica alcun collegamento, , l'identificatore ha il collegamento esterno.

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

errore GCC: dichiarazione extern di una dichiarazione segue senza legame

Qualcuno può spiegarmi perché ottengo questo errore?

Grazie

+1

potrebbe essere la semantica, "specifica alcun legame" contro "specifica 'no linkage'". La promozione automatica in questo caso sembra pazzesca. –

+0

Non capisco la differenza. Potresti elaborare? – mindless

risposta

8

La tua supposizione è corretta: la seconda dichiarazione di a ha il collegamento esterno. Tuttavia, si ottiene un errore perché il codice viola un vincolo in §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.

Cioè, una volta che hai dichiarato a avere alcun collegamento, non si può ridichiarare di nuovo nello stesso ambito.


Un valido esempio di questa regola viene invocata è:

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

Potrebbe fornirmi un esempio valido di: se la dichiarazione precedente non specifica alcun collegamento, l'identificatore ha un collegamento esterno. Non riesco a pensare a nessuno. – mindless

+0

@mindless: ho aggiunto un esempio alla mia risposta. – caf

2

if the prior declaration specifies no linkage

significa

if the prior declaration specifies not a sign of linkage

e non

if the prior declaration specifies that it has no linkage

Questo è confusa e ambigua; non è il solito modo di scrivere uno standard ...

+0

È possibile rimuovere statico, l'errore sarebbe ancora lì. Statico in ambito di blocco non cambia il collegamento, solo la durata di archiviazione. Nell'ambito del file cambia il collegamento, ma non la durata di archiviazione (sempre statica). Un'altra ambiguità in c. – mindless

+0

Ti sbagli; il significato inteso è l'ultimo, esattamente come è scritto. Comunque, non ha alcuna relazione con la domanda. – caf