2014-10-09 5 views
6

मैं पूछना चाहता हूं कि यह अनुवाद इकाइयों में स्ट्रिंग शाब्दिक पते पर भरोसा करने के लिए पोर्टेबल है या नहीं? अर्थात्:अनुवाद इकाइयों में स्ट्रिंग लिटल एड्रेस

एक दिया गया फ़ाइल foo.c एक स्ट्रिंग शाब्दिक "I'm a literal!" के लिए एक संदर्भ है, यह सही और पोर्टेबल भरोसा करने के लिए है कि अन्य दी फ़ाइल में, bar.c उदाहरण में, कि एक ही स्ट्रिंग शाब्दिक"I'm a literal!"उसी स्मृति होगा पता? यह ध्यान में रखते हुए कि प्रत्येक फ़ाइल का अनुवाद .o फ़ाइल में किया जाएगा।

# File foo.c 
/* ... */ 
const char * x = "I'm a literal!" 

# File bar.c 
/* ... */ 
const char * y = "I'm a literal!" 

# File test.c 
/* ... */ 
extern const char * x; 
extern const char * y; 
assert (x == y); //Is this assertion going to fail? 

और एक जीसीसी उदाहरण कमांड लाइन:

gcc -c -o foo.o -Wall foo.c 
gcc -c -o bar.o -Wall bar.c 
gcc -c -o test.o -Wall test.c 
gcc -o test foo.o bar.o test.o 

के बारे में क्या एक ही अनुवाद इकाई में

बेहतर उदाहरण के लिए, एक उदाहरण के कोड इस प्रकार? क्या यह भरोसेमंद होगा यदि स्ट्रिंग्स अक्षर में अनुवाद इकाई में हैं?

+7

नहीं, आप इस पर भरोसा नहीं कर सकते हैं। –

+0

@NeilKirk धन्यवाद नील, मैंने संपादित किया है और एक माध्यमिक प्रश्न जोड़ा है। इसके पीछे कोई भी तर्क महान रोशनी का होगा। –

+2

@fanl - संकलक के दृश्य सी ++ सूट में "स्ट्रिंग पूलिंग" का एक विकल्प है जहां एक ही शाब्दिक के पास एक ही सूचक मूल्य होगा। उस अंतिम वाक्य में मुख्य शब्द * विकल्प * है। इसका तात्पर्य है कि आप इस बात पर भरोसा नहीं कर सकते कि सूचक मान बराबर हैं। – PaulMcKenzie

उत्तर

10

आप समान स्ट्रिंग अक्षर पर समान स्मृति स्थान रखने पर भरोसा नहीं कर सकते हैं, यह एक कार्यान्वयन निर्णय है। C99 draft standard हमें बताता है कि यह अनिर्दिष्ट है एक ही स्ट्रिंग शाब्दिक अलग 6.4.5स्ट्रिंग शाब्दिक हैं कि क्या अनुभाग से,:

यह अनिर्दिष्ट है इन सरणियों प्रदान की उनके तत्वों उचित मान भिन्न हैं या नहीं। यदि कार्यक्रम को इस तरह के सरणी को संशोधित करने का प्रयास करता है, तो व्यवहार अपरिभाषित है।

सी के लिए ++ इस मसौदा मानक खंड 2.14.5स्ट्रिंग शाब्दिक जो कहते हैं में शामिल:

सभी स्ट्रिंग शाब्दिक अलग है (यानि, nonoverlapping वस्तुओं में जमा हो जाती) चाहे कार्यान्वयन परिभाषित किया गया है। स्ट्रिंग अक्षर को संशोधित करने का प्रयास करने वाले का प्रभाव अपरिभाषित है।

संकलक पूल स्ट्रिंग शाब्दिक करने की अनुमति दी है, लेकिन आप को समझने के लिए यह संकलक करने के लिए और इसलिए इस पोर्टेबल नहीं होगा संकलक से काम करता है और संभावित रूप से बदल सकता है के लिए होगा। विजुअल स्टूडियो एक option for string literal pooling

कुछ मामलों में भी शामिल है, समान स्ट्रिंग शाब्दिक निष्पादन योग्य फ़ाइल में अंतरिक्ष को बचाने के लिए जमा किया जा सकता है। स्ट्रिंग-शाब्दिक पूलिंग में, कंपाइलर स्ट्रिंग शाब्दिक के अलग-अलग उदाहरण प्रत्येक संदर्भ बिंदु के बजाय स्मृति में उसी स्थान को इंगित करने के लिए किसी विशेष स्ट्रिंग अक्षर के सभी संदर्भों का कारण बनता है। स्ट्रिंग पूलिंग को सक्षम करने के लिए, /GF कंपाइलर विकल्प का उपयोग करें।

ध्यान दें कि यह साथ अर्हता प्राप्त करता है कुछ मामलों में।

gcc समर्थन पूलिंग और संकलन इकाइयों में करता है और आप -fmerge-constants के माध्यम से इसे चालू कर सकते हैं: समान स्थिरांक (स्ट्रिंग स्थिरांक और फ्लोटिंग प्वाइंट स्थिरांक) संकलन इकाइयों में विलय करने के लिए

प्रयास।

यह विकल्प अनुकूलित संकलन के लिए डिफ़ॉल्ट है यदि असेंबलर और लिंकर इसका समर्थन करता है। इस व्यवहार को बाधित करने के लिए -no-merge-constants का उपयोग करें।

ध्यान दें, प्रयास और यदि का उपयोग करते हैं ... यह समर्थन करते हैं।

स्ट्रिंग शाब्दिक की जरूरत नहीं करने के लिए कम से कम सी के लिए एक तर्क के रूप में जमा किया जाना है कि हम इस archived comp.std.c discussion on string literals कि औचित्य समय में कार्यान्वयन की व्यापक विविधता की वजह से था से देख सकते हैं:

जीसीसी शायद एक उदाहरण के रूप में काम किया हो सकता है लेकिन प्रेरणा के रूप में नहीं। आंशिक रूप से ROMmable डेटा में स्ट्रिंग अक्षर रखने की इच्छा थी, एर, रोमिंग। मैं अस्पष्ट रूप से याद करता हूं कि कुछ सी कार्यान्वयन (X3J11 निर्णय लेने से पहले) जहां स्ट्रिंग अक्षर स्वचालित रूप से एक स्थिर डेटा प्रोग्राम अनुभाग में संग्रहीत या संग्रहीत थे। मौजूदा यूनिक्स गुणों की इच्छा के दौरान अभ्यास की मौजूदा विविधता और की उपलब्धता को देखते हुए, यह स्ट्रिंग अक्षरों की विशिष्टता और उत्तरदायित्व की गारंटी देने के लिए सबसे अच्छा नहीं था।

+1

आपका मतलब है कि दोनों, उम्मीदों की अपेक्षा करते हैं कि अनुवाद इकाइयों में और समान है, अविश्वसनीय हैं? –

+2

@fanl यही वह कहता है। मूल के एंड आर सी में, प्रत्येक स्ट्रिंग शाब्दिक को एक अलग पते के साथ अद्वितीय होने की गारंटी दी गई थी (और आपको स्ट्रिंग अक्षर को संशोधित करने की अनुमति थी); मूल सी मानक ने इसे बदल दिया, और _permitted_ समान स्ट्रिंग अक्षर को एक ही पता रखने के लिए। –

+0

@fanl यह सभी मामलों में अविश्वसनीय है, भले ही कंपाइलर्स पूलिंग का समर्थन करते हैं, 'जीसीसी' और 'विजुअल स्टूडियो' दोनों अपने दस्तावेज़ों में इंगित करते हैं कि यह केवल * कुछ मामलों * में लागू होता है। –

3

नहीं, आप एक ही पते उम्मीद नहीं कर सकते। यदि ऐसा होता है, होता है। लेकिन इसमें कुछ भी लागू नहीं है।

§ 2.14.5/p12

सभी स्ट्रिंग शाब्दिक अलग (अर्थात, nonoverlapping वस्तुओं में जमा हो जाती है) कार्यान्वयन परिभाषित कर रहे हैं या नहीं। स्ट्रिंग अक्षर को संशोधित करने का प्रयास करने वाले का प्रभाव अपरिभाषित है।

संकलक इसे पसंद करते हुए कर सकता है। यदि वे अलग-अलग अनुवाद इकाइयों में हैं या यहां तक ​​कि यदि वे एक ही अनुवाद इकाई में हैं, तो वे अलग-अलग पतों में संग्रहीत किए जा सकते हैं, भले ही वे केवल पढ़ने योग्य स्मृति हों।

MSVC पर, उदाहरण के लिए, पते दोनों ही मामलों में पूरी तरह से अलग हैं, लेकिन फिर से: कुछ भी नहीं संकेत 'मूल्यों (यहां तक ​​कि जहां, जहाँ तक केवल पढ़ने के लिए अनुभाग बाधा के लिए बाध्य है नहीं विलय से संकलक से बचाता है)।

संबंधित मुद्दे