2011-08-30 18 views
6

Następujące identyfikatory nie mają powiązania: identyfikator deklarowany jako coś innego niż obiekt lub funkcja; identyfikator deklarowany jako parametr funkcji; Identyfikator zakresu bloków dla obiektu zadeklarowanego bez specyfikatora klasy pamięci extern.Zakres blokowania C standard

{ 
    static int a; //no linkage 
} 

dla identyfikatora zadeklarowanej z magazynowania klasy specyfikatora extern w zakresie, w którym przed zgłoszenia tego identyfikatora jest widoczne, w przypadku gdy odpowiednie zgłoszenie określa wewnętrzną lub zewnętrzną wiązania, wiązanie identyfikatora w późniejsza deklaracja jest taka sama jak powiązanie określone na wcześniejszej deklaracji. Jeśli nie jest widoczna żadna wcześniejsza deklaracja lub , jeśli wcześniejsza deklaracja nie zawiera żadnego powiązania, , wówczas identyfikator ma połączenie zewnętrzne.

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

Błąd GCC: extern deklaracja następujące oświadczenie bez powiązania

Czy ktoś może mi wyjaśnić dlaczego ten błąd?

Dziękuję

+1

Może być semantyka „określa żadnego powiązania” kontra „określa«nie»podnośnik”. Automatyczna promocja w tym przypadku brzmi szalenie. –

+0

Nie rozumiem różnicy. Czy mógłbyś rozwinąć? – mindless

Odpowiedz

8

Twoje przypuszczenie jest poprawne: druga deklaracja a ma powiązanie zewnętrzne. Jednak pojawia się błąd, ponieważ kod jest niezgodny ograniczenie w §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.

Oznacza to, że kiedy już zadeklarował a mieć żadnego powiązania, nie można redeclare go ponownie w tym samym zakresie.


Ważny przykładem tej zasady jest wywoływana jest:

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

Czy możesz podać ważny przykład: jeśli poprzednia deklaracja nie określa powiązania, identyfikator ma powiązanie zewnętrzne. Nie mogę myśleć o żadnym. – mindless

+0

@mindless: Dodałem przykład do mojej odpowiedzi. – caf

2

if the prior declaration specifies no linkage

oznacza

if the prior declaration specifies not a sign of linkage

i nie

if the prior declaration specifies that it has no linkage

Jest to mylące i niejednoznaczne; nie jest to zwykły sposób na napisanie normy ...

+0

Możesz usunąć statyczne, błąd nadal tam będzie. Statyczny w zakresie bloku nie zmienia powiązania, tylko czas przechowywania. W zasięgu pliku zmienia powiązanie, ale nie czas przechowywania (zawsze statyczny). Kolejna niejednoznaczność w c. – mindless

+0

Mylisz się; zamierzone znaczenie jest ostatnie, dokładnie tak, jak jest napisane. W każdym razie nie ma to wpływu na to pytanie. – caf