सामान्य परिस्थितियों के अंतर्गत (बिना किसी अतिरिक्त जीसीसी झंडे) आप के रूप में इस कोड को संकलित करने के लिए ठीक होना चाहिए:
gcc file1.c file2.c
क्या होने जा रहा है संकलक आप दो वैश्विक चर है कि देखेंगे एक ही चीज़ का नाम दिया और न ही शुरू किया गया है। फिर यह कोड ** कोड के "सामान्य" खंड में आपके अनियमित वैश्विक चर रखेगा। दूसरे शब्दों में यह "पहले" चर की केवल 1 प्रतिलिपि होगी। यह इसलिए होता है क्योंकि gcc
के लिए डिफ़ॉल्ट -fcommon
है आप -fno-common
ध्वज के साथ संकलित करने के लिए अब आप त्रुटि आप के बारे में सोच रहे थे प्राप्त होता थे, तो:
/tmp/ccZNeN8c.o:(.bss+0x0): multiple definition of `first'
/tmp/cc09s2r7.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status
इसके समाधान के लिए आप के लिए extern
जोड़ेंगे सभी चरों में से एक है।
चेतावनी:
अब मान लीजिए कि आप विभिन्न आकार के दो वैश्विक अप्रारंभीकृत सरणियों था करते हैं:
// file1.c
int first[10];
// file2.c
int first[20];
खैर लगता है क्या, उन्हें gcc -Wall file1.c file2.c
साथ संकलन कोई चेतावनी या त्रुटियों और चर का उत्पादन हालांकि यह अलग-अलग आकार का था, हालांकि यह अलग-अलग आकार का था !!!
//objdump from file1.c:
0000000000000028 O *COM* 0000000000000020 first
//objdump from file2.c:
0000000000000050 O *COM* 0000000000000020 first
यह वैश्विक चर के खतरों में से एक है।
** आप * ओ फ़ाइलों की objdump
को देखें, तो (आप gcc -c
साथ संकलित करने के लिए उन्हें उत्पन्न करने के लिए है) आप first
देखेंगे आम (*COM*
) अनुभाग में रखा:
[email protected]:~/C$ objdump -t file2.o
a.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 file2.c
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .rodata 0000000000000000 .rodata
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000004 O *COM* 0000000000000004 first
0000000000000000 g F .text 0000000000000039 main
0000000000000000 *UND* 0000000000000000 f
0000000000000000 *UND* 0000000000000000 printf
जब आप बाहरी रूप में फ़ंक्शन घोषित करते हैं, तो लिंकर इसे अन्य ऑब्जेक्ट्स में खोजेगा। अन्यथा यह उसी फाइल में इसकी तलाश करेगा। – kofemann
यह लिंक भी नहीं करना चाहिए। क्या आप वाकई सभी कंपाइलर और लिंकर चेतावनियां दिखा रहे हैं? –
@KerrekSB लिंक जीसीसी के साथ पूरी तरह ठीक है। 'F' और' main' दोनों से प्रिंटिंग '& first' एक ही पता उत्पन्न करता है। –