2014-04-28 5 views
7

Wikipedia पर बीएसएस आकार निर्धारित करना उल्लेख करता है कि "बीएसएस अनुभाग में आमतौर पर फ़ाइल स्कोप पर घोषित सभी अनियमित चर शामिल हैं।" निम्न फ़ाइल को देखते हुए:ऑब्जेक्ट फ़ाइल

int uninit; 

int main() { 
    uninit = 1; 
    return 0; 
} 

जब मैं एक निष्पादन मैं देख रहा हूँ बीएसएस खंड ठीक से भरा करने के लिए इस संकलन:

$ gcc prog1.c -o prog1 
$ size prog1 
text  data  bss  dec  hex filename 
1115  552  8 1675  68b prog1 

लेकिन अगर मैं एक वस्तु फ़ाइल के रूप में संकलित मैं बीएसएस नहीं दिख रहा है सेगमेंट (मुझे उम्मीद है कि यह 4 हो जाएगा):

$ gcc -c prog1.c 
$ size prog1.o 
text  data  bss  dec  hex filename 
    72   0  0  72  48 prog1.o 

क्या कुछ स्पष्ट है कि मुझे याद आ रही है?

मैं जीसीसी संस्करण 4.8.1 का उपयोग कर रहा हूं।

+0

+1 बहुत अच्छा प्रश्न है। –

+0

'शून्य मुख्य()'? फिर भी? – Jens

+0

हाँ, सुनिश्चित नहीं है कि मुझे यह लिखने के लिए क्या प्रेरित किया गया। तय की। –

उत्तर

5

अगर हम readelf -s का उपयोग प्रतीक तालिका को देखने के लिए, हम देखेंगे:

$ readelf -s prog1.o 

Symbol table '.symtab' contains 10 entries: 
    Num: Value   Size Type Bind Vis  Ndx Name 
    0: 0000000000000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 0000000000000000  0 FILE LOCAL DEFAULT ABS bss.c 
    2: 0000000000000000  0 SECTION LOCAL DEFAULT 1 
    3: 0000000000000000  0 SECTION LOCAL DEFAULT 3 
    4: 0000000000000000  0 SECTION LOCAL DEFAULT 4 
    5: 0000000000000000  0 SECTION LOCAL DEFAULT 6 
    6: 0000000000000000  0 SECTION LOCAL DEFAULT 7 
    7: 0000000000000000  0 SECTION LOCAL DEFAULT 5 
    8: 0000000000000004  4 OBJECT GLOBAL DEFAULT COM uninit  <<<< 
    9: 0000000000000000 16 FUNC GLOBAL DEFAULT 1 main 

हम देखते हैं कि आपके uninit प्रतीक ("चर") इस स्तर पर, एक "आम" प्रतीक में, है। यह अभी तक बीएसएस को "असाइन नहीं किया गया है"।

"आम" प्रतीकों के बारे में अधिक जानकारी के लिए इस सवाल देखें: What does "COM" means in the Ndx column of the .symtab section?

एक बार अपने अंतिम निष्पादन योग्य एक साथ जुड़े हुए है, यह बीएसएस में रखा जाएगा के रूप में आप की उम्मीद है।


आप जीसीसी के लिए -fno-common ध्वज पारित करके इस व्यवहार को बायपास कर सकते हैं:

$ gcc -fno-common -c bss.c 
$ size bss.o 
    text data  bss  dec  hex filename 
    72  0  4  76  4c bss.o 

इसके बजाय, आप static रूप uninit निशान सकता है। इस तरह, संकलक को पता चलेगा कि कोई अन्य .o फ़ाइल इसका संदर्भ नहीं दे सकती है, इसलिए यह "सामान्य" प्रतीक नहीं होगा। इसके बजाय, यह बीएसएस में तुरंत रखा जाएगा, जैसा कि आप की उम्मीद:

$ cat bss.c 
static int uninit; 

int main() { 
    uninit = 1; 
    return 0; 
} 
$ gcc -c bss.c 
$ size bss.o 
    text data  bss  dec  hex filename 
    72  0  4  76  4c bss.o 
+0

धन्यवाद! इससे बहुत मदद मिलती है। –

+0

आपके संपादन भी उत्कृष्ट नोट्स हैं। क्यों stackoverflow भयानक है: डी –

+0

आपका स्वागत है। यह मेरे लिए एक मजेदार अभ्यास था, क्योंकि मैं भी जो देख रहा था उससे उलझन में था। –

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