2016-10-29 126 views
1

7.h:我不明白 「外部」

int a

5.C:

#include"7.h" 
#include <stdio.h> 
int b; 
void way(); 
void way() { 
printf("%p\n",&b); 
} 

6.C:

#include "7.h" 
#include <stdio.h> 
void way(); 
int b; 
int main(int argc, char const *argv[]) 
{ 
way(); 
printf("%p\n",&b); 
return 0; 
} 

爲什麼我使用「gcc -std = c90 5.c 6.c」將其成功編譯!

結果是 0x10288b018 0x10288b018

同一地址!!!!!!但我不使用的extern!爲什麼!

但我改變 「6.C」 到:

6.C:

#include "7.h" 
#include <stdio.h> 
void way(); 
int b=8; 
int main(int argc, char const *argv[]) 
{ 
way(); 
printf("%p\n",&a); 
return 0; 
} 

5.C到:

#include"7.h" 
#include <stdio.h> 
int b=5; 
void way(); 
void way() { 
printf("%p\n",&a); 
} 

結果是:

duplicate symbol _b in: 
    /var/folders/sb/dc6wxwf16kl7k1wrhrxjx5j40000gn/T/5-00d5c1.o 
    /var/folders/sb/dc6wxwf16kl7k1wrhrxjx5j40000gn/T/6-2b050b.o 
ld: 1 duplicate symbol for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
+1

C是一種非常奇怪和奇怪的語言。它有一個「臨時定義」的概念,它確保每個人對變量實際定義的時間都同樣感到困惑。 –

+0

文件'7.h'具有變量定義'int a',這是不好的做法。 –

+0

'int a;'在這種情況下是全局的。 – Stargateur

回答

2

extern關鍵字不是必需的。根據C99標準:

6.7.5.3.17:如果聲明發生在任何函數之外,則標識符具有文件範圍和外部鏈接。

的區別你的兩個例子之間在第6.9.2.4解釋:

int i1 = 1; // definition, external linkage 
int i4;  // tentative definition, external linkage 

的標準說i1是一個定義,而i4暫定定義。有多個定義是一個錯誤;有多個暫定的定義不是。

如果一個實體有一個非試探性的定義,所有暫定的定義都指向它;否則,多個暫定定義是指同一個實體。

+0

@Elliotyang我不會稱之爲「成功」,因爲其中一個定義被忽略而偏向另一個定義。我認爲暫定義的概念不在C90標準中。 – dasblinkenlight

+0

我找到了!C89/C90標準(ISO/IEC 9899:1990): 3.7.2外部對象定義!支架定義符合C90標準。 –

+0

非常感謝! –