सभी #include
कथनों में से पहले linking
के साथ कुछ भी करने की ज़रूरत नहीं है। में #
के साथ कुछ भी याद रखें प्रीप्रोसेसर के लिए है, न कि संकलक या लिंकर।
लेकिन कहा कि समारोह को जोड़ा जाना है ना?
चलो अलग-अलग चरणों में कदम उठाएं।
$ gcc -c -Werror --std=c99 st.c
st.c: In function ‘main’:
st.c:5:22: error: implicit declaration of function ‘isdigit’ [-Werror=implicit-function-declaration]
printf("%d %d\n",isdigit(48),isdigit(48.4));
^
cc1: all warnings being treated as errors
ठीक है जैसा कि आप देखते हैं कि जीसीसी के लिंट (स्थिर विश्लेषक) कार्रवाई में हैं!
जो कुछ भी हम इसे अनदेखा करने के लिए आगे बढ़ना होगा ...
$ gcc -c --std=c99 st.c
st.c: In function ‘main’:
st.c:5:22: warning: implicit declaration of function ‘isdigit’ [-Wimplicit-function-declaration]
printf("%d %d\n",isdigit(48),isdigit(48.4));
इस बार केवल एक चेतावनी। अब हमारे पास वर्तमान निर्देशिका में एक ऑब्जेक्ट फ़ाइल है। के निरीक्षण करते हैं ...
$ nm st.o
U isdigit
0000000000000000 T main
U printf
आप देख सकते हैं printf
और isdigit
दोनों अपरिभाषित रूप में सूचीबद्ध है। तो कोड कहीं से आना है ना?
चलो इसे लिंक करने के लिए आगे बढ़ें ...
$ gcc st.o
$ nm a.out | grep 'printf\|isdigit'
U [email protected]@GLIBC_2.2.5
U [email protected]@GLIBC_2.2.5
अच्छी तरह से आप देख सकते हैं कि स्थिति हल्की सुधार हुई है। isdigit
और printf
असहाय अकेले नहीं हैं जैसे वे st.o
में थे। आप देख सकते हैं कि दोनों कार्य GLIBC_2.2.5
द्वारा प्रदान किए जाते हैं। लेकिन GLIBC
कहां है?
खैर के अंतिम निष्पादन में थोड़ा और अधिक जांच करते हैं ...
$ ldd a.out
linux-vdso.so.1 => (0x00007ffe58d70000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb66f299000)
/lib64/ld-linux-x86-64.so.2 (0x000055b26631d000)
अहा ... है कि वहाँ libc
। तो यह पता चला है, हालांकि आपने कोई निर्देश नहीं दिया है, लिंकर डिफ़ॉल्ट रूप से 3 पुस्तकालयों से जुड़ा हुआ है, उनमें से एक libc
है जिसमें printf
और isdigit
दोनों शामिल हैं।
$gcc -dumpspec
*link:
%{!r:--build-id} %{!static:--eh-frame-hdr} %{!mandroid|tno-android-ld:%{m16|m32|mx32:;:-m elf_x86_64} %{m16|m32:-m elf_i386} %{mx32:-m elf32_x86_64} --hash-style=gnu --as-needed %{shared:-shared} %{!shared: %{!static: %{rdynamic:-export-dynamic} %{m16|m32:-dynamic-linker %{muclibc:/lib/ld-uClibc.so.0;:%{mbionic:/system/bin/linker;:/lib/ld-linux.so.2}}} %{m16|m32|mx32:;:-dynamic-linker %{muclibc:/lib/ld64-uClibc.so.0;:%{mbionic:/system/bin/linker64;:/lib64/ld-linux-x86-64.so.2}}} %{mx32:-dynamic-linker %{muclibc:/lib/ldx32-uClibc.so.0;:%{mbionic:/system/bin/linkerx32;:/libx32/ld-linux-x32.so.2}}}} %{static:-static}};:%{m16|m32|mx32:;:-m elf_x86_64} %{m16|m32:-m elf_i386} %{mx32:-m elf32_x86_64} --hash-style=gnu --as-needed %{shared:-shared} %{!shared: %{!static: %{rdynamic:-export-dynamic} %{m16|m32:-dynamic-linker %{muclibc:/lib/ld-uClibc.so.0;:%{mbionic:/system/bin/linker;:/lib/ld-linux.so.2}}} %{m16|m32|mx32:;:-dynamic-linker %{muclibc:/lib/ld64-uClibc.so.0;:%{mbionic:/system/bin/linker64;:/lib64/ld-linux-x86-64.so.2}}} %{mx32:-dynamic-linker %{muclibc:/lib/ldx32-uClibc.so.0;:%{mbionic:/system/bin/linkerx32;:/libx32/ld-linux-x32.so.2}}}} %{static:-static}} %{shared: -Bsymbolic}}
क्या अन्य दो पुस्तकालयों हैं:
आप द्वारा लिंकर के डिफ़ॉल्ट व्यवहार को देख सकते हैं?
खैर याद है जब आप a.out
में खोदे गए, दोनों printf
और isdigit
अभी भी U
अज्ञात मतलब यह है कि के रूप में दिखाया गया है। दूसरे शब्दों में, इन प्रतीकों से जुड़े memory
पते नहीं थे।
असल में यह जादू है। इन पुस्तकालयों को वास्तव में रनटाइम के दौरान लोड किया गया था, पुराने सिस्टम जैसे लिंक समय के दौरान नहीं।
यह कैसे कार्यान्वित किया जाता है? वैसे यह एक शब्दजाल है, आलसी लिंकिंग जैसे कुछ। यह क्या करता है, जब प्रक्रिया कोई फ़ंक्शन कॉल करती है, यदि कोई मेमोरी पता नहीं है (टेक्स्ट अनुभाग), तो यह Trap
उत्पन्न करता है (कुछ उच्च स्तरीय भाषा शब्दकोष में अपवाद की तरह, जब भाषा इंजन पर नियंत्रण दिया जाता है)। कर्नेल इस तरह के Trap
को अवरुद्ध करता है और इसे गतिशील लोडर पर ले जाता है जो लाइब्रेरी लोड करता है और कॉलर प्रक्रिया में संबंधित मेमोरी पता देता है।
कई सैद्धांतिक कारण हैं, क्यों चीजें करना आलसी पहले से करने से बेहतर है। मुझे लगता है कि यह एक नया विषय है, जिसे हम किसी अन्य समय चर्चा करेंगे।
क्या यह ctype.h redefines मैक्रो के रूप में isdigit हो सकता है? –
@WouterHuysentruit नहीं, मैं कुछ छुपा नहीं रहा हूँ। इसके अलावा, यदि आपने अभी प्रोग्राम की प्रतिलिपि बनाई है और विचारधारा में चिपकाया है तो यह संकलन और जीसीसी 5.1 पर ठीक जुड़ा हुआ लगता है, लेकिन यह दुर्घटनाग्रस्त हो जाता है। – user1537366