2012-01-04 17 views
20

सभी प्रारंभिक वैश्विक/स्थैतिक चर प्रारंभिक डेटा अनुभाग पर जाएंगे। सभी अनियमित वैश्विक/स्थैतिक चर अनियंत्रित डेटा अनुभाग (बीएसएस) पर जाएंगे। कार्यक्रम लोड समय के दौरान बीएसएस में चर मूल्य 0 प्राप्त होंगे।यदि कोई वैश्विक चर 0 पर शुरू किया गया है, तो यह बीएसएस पर जाएगा?

यदि कोई वैश्विक चर स्पष्ट रूप से शून्य (int myglobal = 0) में प्रारंभ किया गया है, तो वह चर संग्रहीत किया जाएगा?

+4

int put_me_somewhere = 0; int main(int argc, char* argv[]) { return 0; } 

कोई विकल्प (परोक्ष -fzero-initialized-in-bss) के साथ संकलन क्या हुआ जब आप इसे आजमाते हैं? आप देख सकते हैं कि 'objdump -x' का उपयोग करके '.o' फ़ाइल में क्या है। –

+0

मैंने ए से नीचे की कोशिश की)। Int globalvar = 0; objdump -x परीक्षण> 1.txt बी) .for ==> int globalvar; objdump -x परीक्षण> 2.txt और diff है: - 2 .bss 00000004 00000000 00000000 00000058 2 ** 2 + 2 .bs 00000000 00000000 00000000 00000058 2 ** 2 -00000000 जी ओ।बीएसएस 00000004 globalvar +00000004 ओ * COM * 00000004 globalvar –

+0

@ लूनर मशरूम अपडेट पोस्ट * अहम * :) –

उत्तर

26

कंपाइलर ऐसे चर को bss के साथ-साथ data में रखने के लिए स्वतंत्र है। उदाहरण के लिए, जीसीसी एक special option को नियंत्रित इस तरह के व्यवहार है: लक्ष्य एक बीएसएस अनुभाग का समर्थन करता है

-fno-zero-initialized-in-bss

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

डिफ़ॉल्ट -fzero-initialized-in-bss है।

निम्न उदाहरण (test.c फ़ाइल) के साथ की कोशिश की:

$ touch test.c && make test && objdump -x test | grep put_me_somewhere 
cc  test.c -o test 
0000000000601028 g  O .bss 0000000000000004    put_me_somewhere 

-fno-zero-initialized-in-bss विकल्प के साथ संकलन:

$ touch test.c && make test CFLAGS=-fno-zero-initialized-in-bss && objdump -x test | grep put_me_somewhere 
cc -fno-zero-initialized-in-bss test.c -o test 
0000000000601018 g  O .data 0000000000000004    put_me_somewhere 
+1

दिलचस्प प्रतिष्ठा, आपके पास है। –

+1

@EknathIyer मैंने इसे तोड़ दिया :( –

+0

दिनम, बहुत बुरा, एल्डर –

6

यह आसान एक विशिष्ट संकलक के लिए परीक्षण करने के लिए काफी है:

$ cat bss.c 
int global_no_value; 
int global_initialized = 0; 

int main(int argc, char* argv[]) { 
    return 0; 
} 
$ make bss 
cc  bss.c -o bss 
$ readelf -s bss | grep global_ 
    32: 0000000000400420  0 FUNC LOCAL DEFAULT 13 __do_global_dtors_aux 
    40: 0000000000400570  0 FUNC LOCAL DEFAULT 13 __do_global_ctors_aux 
    55: 0000000000601028  4 OBJECT GLOBAL DEFAULT 25 global_initialized 
    60: 000000000060102c  4 OBJECT GLOBAL DEFAULT 25 global_no_value 

हम 0000000000601028 और 000000000060102c के स्थान की तलाश कर रहे:

$ readelf -S bss 
There are 30 section headers, starting at offset 0x1170: 

Section Headers: 
    [Nr] Name    Type    Address   Offset 
     Size    EntSize   Flags Link Info Align 
... 
    [24] .data    PROGBITS   0000000000601008 00001008 
     0000000000000010 0000000000000000 WA  0  0  8 
    [25] .bss    NOBITS   0000000000601018 00001018 
     0000000000000018 0000000000000000 WA  0  0  8 

ऐसा लगता है कि दोनों मूल्यों की तरह .bss में जमा हो जाती मेरे सिस्टम पर अनुभाग: gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)

1

व्यवहार सी कार्यान्वयन पर निर्भर है। यह या तो .data या .bss में समाप्त हो सकता है, और उन परिवर्तनों को बढ़ाने के लिए जो इसे समाप्त नहीं करते हैं। डेटा को अनावश्यक स्थान लेना, यह बेहतर है कि इसे 0 पर स्पष्ट रूप से प्रारंभ न करें, क्योंकि यह 0 पर सेट हो जाएगा वस्तु स्थिर अवधि का है।

+0

यह प्रश्न जीसीसी टैग किया गया है (हालांकि संस्करण/लक्ष्य निर्दिष्ट नहीं है)। –

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