2012-04-18 11 views
12

मैं इस तरह के एक संरचना है (किसी कारण मैं सिर्फ एक सरणी का उपयोग नहीं कर सकते के लिए):sizeof सदस्य गणना त्रुटि

struct OperatorData 
    { 
    char m_record_0[RIX_OPERATOR_CONFIG_SIZE]; 
    char m_record_1[RIX_OPERATOR_CONFIG_SIZE]; 
    //.... 
    char m_record_9[RIX_OPERATOR_CONFIG_SIZE]; 
    }; 

और मैं संकलन समय पर खेतों की मात्रा की गणना करने के लिए कोशिश कर रहा हूँ:

enum {fieldsAmount = sizeof(OperatorData)/sizeof(OperatorData::m_record_0)}; 

और संकलक रिपोर्ट में इस तरह के संदेश:

Error: #245: a nonstatic member reference must be relative to a specific object 
    enum{fieldsAmount = sizeof(OperatorData)/sizeof(OperatorData::m_record_0)}; 
                   ^

मैं keil uVision3 V3.60 का उपयोग करें। इससे कोई फर्क नहीं पड़ता कि मैं संरचना के अंदर या बाहर एनम घोषणा कहां रखता हूं। संकलक इस membmer का आकार क्यों नहीं ले सकता है?

+0

'sizeof' का तर्क एक प्रकार (यहाँ सच नहीं है) या एक एल मूल्य होना चाहिए में उपयोग करना होगा (यह भी सच नहीं है)। – Matthias

+0

@ माथियास: ऑपरेंड को _lvalue_ होना जरूरी नहीं है; किसी भी अभिव्यक्ति की अनुमति है, जब तक इसका प्रकार 'आकार' के लिए उपयुक्त है। –

+2

आपको यहां वर्णित डेटा संरेखण पर विचार करना चाहिए, जैसा कि यहां वर्णित है http://stackoverflow.com/a/10207185/147763 –

उत्तर

12

ऐसा लगता है कि आपका कंपाइलर सी ++ 11 का समर्थन नहीं करता है जो Type::member के अनगिनत अभिव्यक्तियों के उपयोग की अनुमति देता है।

OperatorData* noImpl(); 

enum{fieldsAmount = sizeof(OperatorData)/sizeof(noImpl()->m_record_0)}; 
+0

+1। अच्छा है। मुझसे बेहतर! – Nawaz

+1

वैसे, 'ऑपरेटरडाटा नोआईएमएल();' भी ठीक है। फिर आपको 'sizeof (noImpl()। M_record_0) लिखना होगा। – Nawaz

+0

'NoImpl' फ़ंक्शन नहीं है? –

0

ऐसा इसलिए है क्योंकि m_record_0 संरचना OperatorData संरचना का स्थिर सदस्य नहीं है। आप केवल तभी ऐसा कर सकते हैं जब यह स्थिर सदस्य हो।

+0

लेकिन संकलन समय पर ज्ञात फ़ील्ड का आकार नहीं है? –

+0

हां, आकार एक संकलन-समय ऑपरेटर है जो सही है। समस्या यह है कि आप ऑपरेटरडेटा :: m_record_0 द्वारा सदस्य को संदर्भित नहीं कर सकते हैं, जब कोई m_record_0 आपकी संरचना का स्थिर सदस्य नहीं है। –

0

अपनी संरचना का एक ऑब्जेक्ट बनाएं और sizeof() ऑपरेटर का उपयोग करें।

4

मुझे नहीं लगता कि यह सुरक्षित है; सदस्यों के बीच या उसके बाद पैडिंग जोड़ा जा सकता है, जिसे sizeof (OperatorData) में शामिल किया जाएगा लेकिन किसी विशिष्ट सदस्य के आकार में नहीं।

बेशक आप पहले से ही उपलब्ध RIX_OPERATOR_CONFIG_SIZE मान का उपयोग एक सन्निकटन प्राप्त करने के लिए कर सकता है: यह मानते हुए

const size_t num_records = sizeof (OperatorData)/RIX_OPERATOR_CONFIG_SIZE; 

केवल char सरणियों के लिए प्रयोग किया जाता है, और यह किसी भी गद्दी बौने कि। फिर

const size_t num_records = sizeof (OperatorData)/
     (offsetof(OperatorData, m_record_1) - offsetof(OperatorData, m_record_0)); 

ध्यान दें, कि यह भी सिर्फ एक सन्निकटन है:

तुम भी offsetof() उपयोग कर सकते हैं, इस के सदस्यों के बीच कम से कम गद्दी सहित को लाभ मिलता है। उम्मीद है कि, कोई भी पैडिंग सदस्यों की तुलना में बहुत छोटी होगी ताकि उनके योगदान को गोल किया जा सके।

3

:: ऑपरेटर का उपयोग कर एक गैर स्थैतिक सदस्य तक नहीं पहुंचा जा सकता है।

सी ++ 11 में, आप यह कर सकते हैं (quick demo):

#include <utility> 

size = sizeof(OperatorData)/sizeof(std::declval<OperatorData>().m_record_0); 

और में सी ++ 03, ऐसा करते हैं:

size = sizeof(OperatorData)/sizeof(((OperatorData*)(0))->m_record_0); 

अभिव्यक्ति ((OperatorData*)(0)) के प्रकार OperatorData* है , इसलिए मैं आकार प्राप्त करने के लिए ((OperatorData*)(0))->m_record_0 का उपयोग करता हूं जो लगभग बराबर है:

OperatorData* od = ((OperatorData*)(0)); 
size_t size = sizeof(od->m_record_0); 

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

5

उपयोग typedefs:: आप सही प्रकार की अभिव्यक्ति का निर्माण करना होगा, जैसे कुछ

typedef char RecordType[RIX_OPERATOR_CONFIG_SIZE]; 

struct OperatorData 
{ 
    RecordType m_record_0; 
    RecordType m_record_1; 
    //.... 
    RecordType m_record_9; 
}; 

तब:

enum {fieldsAmount = sizeof(OperatorData)/sizeof(RecordType)}; 
+0

+1: मैन, तुम मुझसे जल्दी हो;) –

2

आप पहली बार सही संरेखण सेट करने के लिए संकलक स्टूमा का उपयोग (http://msdn.microsoft.com/en-us/library/2e70t5y1(v=vs.80).aspx विजुअल स्टूडियो में, http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html जीसीसी में) अन्यथा sizeof(OperatorData) कुछ भी हो सकता है।

तो फिर तुम OperatorData का एक उदाहरण है जिसमें से आप रिकॉर्ड को लेने और उन्हें sizeof()

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