निम्नलिखित कोड पर विचार करें:जीसीसी अलग-अलग क्षेत्रों में स्थानीय यूनियनों के लिए अलग-अलग स्टैक स्पेस आवंटित क्यों करता है?
#include <stdlib.h>
#ifndef TRY
#define TRY struct
#endif
TRY testme
{
int one;
int two;
char three;
int four;
};
int
main (void)
{
{
volatile TRY testme one;
one.one = 2;
one.three = 7;
}
{
volatile TRY testme twos;
twos.one = 3;
}
{
volatile TRY testme one;
one.one = 4;
}
{
volatile TRY testme twos;
twos.one = 5;
}
{
volatile TRY testme twos;
twos.one = 6;
}
{
volatile TRY testme twos;
twos.one = 6;
}
return EXIT_SUCCESS;
}
संकलित रूप में 86 के लिए है (जिसका अर्थ है testme एक struct है), ढेर आकार संकलक मुख्य के लिए आवंटित 16 बाइट्स है।
$ gcc -DTRY=union -g -O2 test.c -o test
$ objdump -d ./test | ./checkstack.pl i386 | grep main
इसके अलावा, struct के किसी भी अतिरिक्त उदाहरण:
$ gcc -g -O2 test.c -o test
$ objdump -d ./test | ./checkstack.pl i386 | grep main
16 main
हालांकि, TRY संघ को परिभाषित के साथ संकलित (जिसका अर्थ है testme एक संघ है), ढेर आकार संकलक मुख्य के लिए आवंटित 32 बाइट्स/अतिरिक्त क्षेत्रों में परिभाषित संघ, संघ का उपयोग करते समय बड़े ढेर आवंटन का उत्पादन करेगा, लेकिन संरचना के रूप में उपयोग किए जाने पर स्टैक आवंटन को विस्तारित नहीं करेगा।
अब, यह समझ में नहीं आता है - संघ को कम स्टैक स्पेस लेना चाहिए, अगर नहीं, तो अधिक नहीं, फिर एक ही फ़ील्ड के साथ एक संरचना!
ऐसा लगता है जैसे जीसीसी यूनियनों को अलग-अलग क्षेत्रों में भी समवर्ती रूप से उपयोग करता है, लेकिन structs के लिए ऐसा नहीं करता है।
कुछ और स्पष्टीकरण:
अस्थिर दूर कार्य के अनुकूलन से संकलक को रोकने के लिए प्रयोग किया जाता है। अस्थिरता को खोना और अनुकूलन के साथ संकलन एक ही परिणाम उत्पन्न करता है।
भले ही टेस्टमे एक ऐसी संरचना है जिसमें सदस्यों में से एक के रूप में संघ है, वही व्यवहार देखा जाता है। दूसरे शब्दों में - यह पर्याप्त है कि संरचना के सदस्यों में से एक अलग-अलग स्टैक आवंटन के लिए जीसीसी के लिए एक संघ है।
कंपाइलर जीसीसी संस्करण 4.4.3 (उबंटू 4.4.3-4ubuntu5) है लेकिन अन्य आर्किटेक्चर के लिए अन्य जीसीसी संस्करणों ने वही व्यवहार दिखाया है।
checkstack.pl केवल स्टैक आवंटित करने के लिए उपयोग किए गए निर्देशों के लिए objdump आउटपुट की खोज करता है (स्टैक पॉइंटर से सब)।
मेरा प्रश्न:
- क्यों जीसीसी इस करता है? क्या यह एक बग है या इस व्यवहार के लिए कोई कारण है?
- मान लीजिए कि यह एक बग नहीं है, क्या इसके आसपास काम करने का एक तरीका है और यूनियनों के समान स्टैक्ट्स के लिए स्टैक आवंटित करने के लिए जीसीसी को मजबूर करना है।
स्पष्टीकरण: क्यों struct या संघ अपनी ओर के आकार से आकार में बड़ा हो गया लगता है मेरा प्रश्न नहीं है। मैं समझता हूं कि संरेखण के लिए पैडिंग का कारण है। मेरी समस्या यह है कि संकलक यूनियन के विभिन्न उदाहरणों के लिए एकाधिक स्टैक फ्रेम आवंटित करता है, भले ही उन्हें विभिन्न क्षेत्रों में परिभाषित किया गया हो, जबकि यह नहीं होना चाहिए और वास्तव में एक ही फ़ील्ड के साथ संरचना के लिए ऐसा नहीं करना चाहिए।
धन्यवाद!
हो सकता है कि यूनियनों के साथ-साथ '-O2' (अभी तक) पर अनुकूलित नहीं कर रहे हैं? जेनरेट असेंबलर कोड पर एक नज़र डालें। 'सख्त-एलियासिंग' को अक्षम करने का भी प्रयास करें। ओह, और एक मौजूदा जीसीसी आज़माएं। –
क्या आपने [इस सवाल] पर एक नज़र डाली है (http://stackoverflow.com/questions/8453881/sizeof-union-larger-than-expected-how-does-type-alignment-take-place-here) और [ यह एक] (http://stackoverflow.com/questions/7212585/why-is-my-unions-size-bigger-than-i-expected)? ऐसा लगता है कि पैडिंग और संरेखण बाधाओं का मामला – Coren
@ एनी-मूस -फनो-सख्त-एलियासिंग एक ही परिणाम उत्पन्न करता है। मैं परीक्षण करने के लिए नवीनतम जीसीसी का निर्माण कर रहा हूँ। – gby