2016-03-21 11 views
1

ben karıştı neden şu işleri:C de değişken için extern ihmal, ama hala çalışır?

test.c

#include <stdio.h> 

int g; 
// ??? should be extern int g; ??? 

int main(){ 
    printf("%i\n", g); 
    return 0; 
} 

lib.c

int g = 3;

Neden derleme üzerine yinelenen sembol hata alamıyorum? C++ 'da bunu yapmaya çalışırken hata alıyorum, bu da beni tatmin ediyor. Ancak, bu örnekte, her şey extern'i dahil edip etmediğimi (yani başarılı bir şekilde 3 basar) derler ve çalışır. C'deki extern hakkında StackOverflow hakkındaki diğer tüm soruları okumaktan herkes, bir değişkende kullanılan extern'in değişkeni tanımladığını, ancak bunun için tanımladığı (yani bellek ayırma) olduğunu söyler. Ama burada, eğer extern kullanmazsam, o zaman her ikisi de g olarak adlandırılan iki ayrı değişken tanımlıyorum, bu yüzden bir çeşit yinelenen sembol hatası olmalı. Ama yok, o yüzden kafam çok karıştı.

+0

'lib.c: Sonuç olarak, "test.c" olarak g değeri de 3.

See başlangıca getirilir "lib.c", içinde g değinmektedir '? – Carcigenicate

+0

Nasıl derlersiniz? –

+0

Bu garip C (ama C++ değil) şeyler. Buraya bakın: http://stackoverflow.com/questions/3095861/about-tentative-definition veya burada: http://ninjalj.blogspot.ch/2011/10/tentative-definitions-in-c.html –

cevap

1

N1570, 6.9.2 (vurgu madeni):

2 A, bir başlatıcı olmadan kapsamı dosya sahip bir nesne için bir tanımlayıcı beyanı ve bir depolama sınıf belirleyici olmayan veya ile Depolama sınıfı belirteci statik, geçici tanımını oluşturur.

4 Örnek 1

 int i1 = 1;     // definition, external linkage 
     static int i2 = 2;    // definition, internal linkage 
     extern int i3 = 3;    // definition, external linkage 
     int i4;      // tentative definition, external linkage 
     static int i5;     // tentative definition, internal linkage 
     int i1;      // valid tentative definition, refers to previous 
     int i2;      // 6.2.2 renders undefined, linkage disagreement 
     int i3;      // valid tentative definition, refers to previous 
     int i4;      // valid tentative definition, refers to previous 
     int i5;      // 6.2.2 renders undefined, linkage disagreement 
     extern int i1;   // refers to previous, whose linkage is external 
     extern int i2;   // refers to previous, whose linkage is internal 
     extern int i3;   // refers to previous, whose linkage is external 
     extern int i4;   // refers to previous, whose linkage is external 
     extern int i5;   // refers to previous, whose linkage is internal 

daki "test.c" olarak int g;g dış bağlantı (örneklere bakınız) elde geçici bir tanımdır. Ancak, "lib.c" içindeki int g = 3; bir başlatıcıya sahiptir, bu nedenle geçici bir tanım değildir. http://en.cppreference.com/w/c/language/extern Eğer dahil değildir