2014-09-12 5 views
9
#include <iostream> 

using namespace std; 

class Empty{ 
    char omg[0]; 
}; 

int main() 
{ 
    Empty em1, em2; 
    Empty set[100]; 
    cout << sizeof(Empty) << " " << sizeof(em1) << " " << sizeof(em2) << endl; 
    cout << (long*)&em1 << " " << (long*)&em2 << endl; 

    cout << "total numbers of element is: " << sizeof(set)/sizeof(*set) << endl; 

    return 0; 
} 

इसका उत्पादन होता है:कुछ

0xbff36ad0 0xbff36ac8

तत्वों की संख्या है: 4

परिणाम हैं बहुत आश्चर्यजनक

ऊपर दिखाए गए अनुसार, खाली एक वर्ग है, इसका आकार और इसकी वस्तुएं सभी 0 हैं, क्यों?

शायद मुझे लगता है, क्योंकि एक खाली वर्ग का आकार 1 है, और जब कक्षा खाली नहीं है, तो इसका आकार सदस्यों द्वारा तय किया जाता है, लेकिन यहां इसका सदस्य विशेष है, यह लंबाई शून्य की सरणी है, और यह सरणी आकार 0 है, इसलिए वर्ग और वस्तुओं का आकार सभी 0

यह मेरा अनुमान है। कार्यक्रम चलने के रूप में, हम देख सकते हैं कि दोनों वस्तुओं में पता है, और पता अलग है।

यहां मेरा प्रश्न है: यदि 0 आकार का ऑब्जेक्ट लागू किया जा सकता है, तो सी ++ मानक कहता है कि खाली वस्तुओं का आकार() = 1 है, यह "यह सुनिश्चित करने के लिए है कि दो अलग-अलग वस्तुओं के पते अलग होंगे" Why is the size of an empty class not zero?, लेकिन अब, हमारे पास उत्पादन के रूप में अलग पता है, यह कैसे होता है?

और भी, कोई फर्क नहीं पड़ता कि सरणी सेट का आकार क्या है, आखिरी लाइन आउटपुट हमेशा 4 है, क्यों?

धन्यवाद :)

पुनश्च: मैं MacOS पर इस कार्यक्रम चलाने के लिए, और संकलक एप्पल LLVM संस्करण 5.1 (बजना-503.0.40) (LLVM 3.4svn के आधार पर)

+5

शून्य आकार के सरणी गैर मानक हैं (वास्तव में मानक स्पष्ट रूप से उन्हें मना करता है), इसलिए मानक के बारे में आपका प्रश्न मंथन है। आकार के लिए, यदि आपका कंपाइलर 'आकार (खाली) == 0' मानता है तो आप शून्य से विभाजित होते हैं, जो अपरिभाषित व्यवहार है। – user657267

+1

एफडब्ल्यूआईडब्ल्यू; msvc आउटपुट 'त्रुटि C2233:' set ': शून्य-आकार वाले सरणी वाले ऑब्जेक्ट्स के सरणी अवैध हैं – Niall

+1

आप शून्य आकार के सरणी (एक्सटेंशन) और डाइविंग शून्य से –

उत्तर

1

मैं लूँगा है एक स्टैब के बाद से कोई भी अनुभवी नहीं है:

ऊपर दिखाए गए अनुसार, खाली एक वर्ग है, इसका आकार और इसकी वस्तुएं सभी 0 हैं, क्यों?

शून्य आकार सरणियों, मानक द्वारा अनुमति नहीं है इसलिए जहाँ तक मानक sizeof(Empty) का संबंध है, एक अर्थहीन अभिव्यक्ति है आप पहले से ही अपरिभाषित व्यवहार के दायरे में हैं।

यहां मेरा प्रश्न है: यदि 0 आकार का ऑब्जेक्ट लागू किया जा सकता है, [...] खाली वर्ग का आकार शून्य क्यों नहीं है? , लेकिन अब, हमारे पास उत्पादन के रूप में अलग पता है, यह कैसे होता है?

जैसा कि ऊपर, आकार 0 का एक उद्देश्य के लिए एक वैध मानक C++ कार्यक्रम में मौजूद नहीं कर सकते (आधार वर्ग subobjects को छोड़कर)।

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

आपका कंपाइलर em1 और em2 के लिए अलग-अलग पते प्रदान करने के लिए पर्याप्त बुद्धिमान है, लेकिन आपको यह पता होना चाहिए कि set के सभी तत्व वास्तव में एक ही पते हैं।

और भी, कोई फर्क नहीं पड़ता कि सरणी सेट का आकार क्या है, आखिरी लाइन आउटपुट हमेशा 4 है, क्यों?

के बाद से अपने संकलक sizeof(Empty) और Empty के एरे समझता है शून्य होने के लिए आपको शून्य से भाग देने रहे हैं, जो अपरिभाषित व्यवहार है। यदि आप ऑप्टिमाइज़ेशन अक्षम करते हैं तो आपको प्रोग्राम प्रोग्राम क्रैश हो सकता है, उदाहरण के लिए जीसीसी के साथ आपका प्रोग्राम -O0 के साथ क्रैश हो जाता है लेकिन -O1 के साथ नहीं।