निम्नलिखित C++ स्रोत कोड पर विचार करें की ओर जाता है। 4 और क्लैंग-3.6.0 उबंटू 14.04 के तहत। अजीब व्यवहार यह है कि एक स्थिर आवंटित सरणी _end
के अंत में, _end
अंक इसकी शुरुआत में नहीं है। यदि हम _end
को end_
के साथ प्रतिस्थापित करते हैं, तो सब कुछ ठीक काम करता है।ग्राम में ++ प्रतीक '_end' का उपयोग करते हुए एक विभाजन गलती
$ g++ main.cpp -o main.s -O0 -S
$ g++ main2.cpp -o main2.s -O0 -S
$ diff main.s main2.s
1,2c1,2
< .file "main.cpp"
< .globl _end
---
> .file "main2.cpp"
> .globl end_
5,7c5,7
< .type _end, @object
< .size _end, 4200
< _end:
---
> .type end_, @object
> .size end_, 4200
> end_:
25c25
< movl $0, _end(,%rax,4)
---
> movl $0, end_(,%rax,4)
:
इसके अलावा, अगर हम एस कमांड लाइन तर्क प्रदान करके एक विधानसभा कोड उत्पादन के लिए जीसीसी से पूछते हैं, वहाँ "_end" और किसी भी अन्य सरणी नाम के साथ संस्करण के साथ संस्करण के बीच कोई महत्वपूर्ण अंतर हो जाएगा
$ g++ main.cpp -o main -O0
$ g++ main2.cpp -o main2 -O0
$ objdump -d main >main.dump
$ objdump -d main2 > main2.dump
$ diff main.dump main2.dump
2c2
< main: формат файла elf64-x86-64 // "File format" in Russian
---
> main2: формат файла elf64-x86-64
123c123
< 4004ff: c7 04 85 c8 20 60 00 movl $0x0,0x6020c8(,%rax,4)
---
> 4004ff: c7 04 85 60 10 60 00 movl $0x0,0x601060(,%rax,4)
जहां तक:
लेकिन अगर हम objdump का उपयोग निष्पादनयोग्य डंप और उनके खिलाफ diff चलाने के लिए, हम _end
संस्करण का उपयोग किया पते में देखेंगे की जरूरत की तुलना में 4200 = 4 * 1050 बाइट्स आगे है मुझे पता है, जीसीसी कंपाइलर variab का इलाज कर सकते हैं लेस अंडरस्कोर से शुरू होता है जैसा कि यह चाहता है, i। ई। यह आपके कोड में ऐसे प्रतीकों का उपयोग करने का एक बुरा अभ्यास है। लेकिन मेरा सवाल है: वास्तव में यहां क्या होता है? क्यों _end
आवंटित सरणी के अंत के पते के साथ प्रतिस्थापित किया गया है? यदि हम "-S" कमांड लाइन तर्क का उपयोग करते हैं तो कोई फर्क नहीं पड़ता है, लेकिन वास्तव में निर्मित बाइनरी में कोई अंतर है? इस मामले में जीसीसी और क्लैंग समान रूप से व्यवहार नहीं करते हैं, यह मेरे लिए भी अजीब है।
बिल्कुल मुझे जो चाहिए, धन्यवाद! लेकिन क्यों "-S" कमांड लाइन तर्क इस कोड को संकलित करते समय संदिग्ध कुछ भी नहीं दिखाता है? –
@MaximAkhmedov शायद ऐसा इसलिए है क्योंकि '_end' किसी भी अन्य पॉइंटर्स के रूप में एक सूचक है, और जब आप अपनी सरणी को असाइन करते हैं तो पॉइंटर अंकगणित किया जाता है। – vsoftco