2010-06-28 15 views
19

मैं MinGW जीसीसी 4.4.0 में कुछ C++ कोड संकलन कर रहा हूँ, और निम्न फार्म के साथ चेतावनी मिल ...ऑफ़सेट के इस उपयोग के साथ क्या गलत है?

warning: invalid access to non-static data member '<membername>' of NULL object 
warning: (perhaps the 'offsetof' macro was used incorrectly) 

यह समस्या लगता है परिचित - कुछ मैंने पहले हल करने की कोशिश की और विफल रहा है, मैं सोचो, लेकिन थोड़ी देर पहले। कोड विजुअल सी ++ में ठीक बनाता है, लेकिन मैंने हाल ही में किसी अन्य कंपाइलर में यह विशेष कोड नहीं बनाया है।

समस्या कोड निम्न टेम्पलेट है ...

template<typename T> 
class c_Align_Of 
{ 
    private: 
    struct c_Test 
    { 
     char m_Char; 
     T m_Test; 
    }; 
    public: 
    enum { e_Align = offsetof (c_Test, m_Test) }; 
}; 

जाहिर है मैं शायद कुछ सशर्त संकलन इस के लिए संकलक विशिष्ट कार्यों का उपयोग करने के लिए उपयोग कर सकते हैं, और मेरा मानना ​​है कि C++ 0x (पर लंबी होगा पिछले) इसे अनावश्यक बनाओ। लेकिन किसी भी मामले में, मैं offsetof के इस उपयोग के साथ कुछ भी गलत नहीं देख सकता।

बहुत pedantically, यह है कि क्योंकि T पैरामीटर प्रकार कभी कभी गैर पॉड हैं, इसलिए जीसीसी कक्षाएं c_Test रूप में गैर-पॉड संभव है और शिकायत (और शिकायत और शिकायत - मैं हो रही है इन चेतावनियों के लगभग 800 लाइनों) ।

यह मानक की सख्त शब्दावली से शरारती है, क्योंकि गैर-पीओडी प्रकार offsetof तोड़ सकते हैं। हालांकि, इस तरह के गैर-पीओडी अभ्यास में कोई समस्या नहीं होनी चाहिए - c_Test में वर्चुअल टेबल नहीं होगा, और m_Test के ऑफसेट को खोजने के लिए कोई रन-टाइम ट्रिकरी की आवश्यकता नहीं है।

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

इसके अलावा, मैं केवल एक ही व्यक्ति यहाँ जो बात इस तरह का नहीं हूँ ...

Answer to legit-uses-of-offsetof question

मुझे क्या करना याद कारण इस तरह का के लिए offsetof साथ कोई समस्या आ, लेकिन मुझे नहीं लगता समस्या यह टेम्पलेट था।

कोई विचार?

+0

क्या आप उन पीओडी-प्रकारों के लिए एक उदाहरण जोड़ सकते हैं जो समस्या को पुन: उत्पन्न करते हैं? –

+0

@ जॉर्ज - कोई बात नहीं - मैं सीधे सोच नहीं रहा था। उनके पास रचनाकार थे और इस प्रकार गैर-पीओडी थे। नीचे जवाब देखें। – Steve314

उत्तर

33

ओह ...

मुद्दा टी प्रकार गैर पॉड होने के कारण c_Test struct गैर पॉड होने के साथ है। यहाँ जीसीसी पुस्तिका से एक उद्धरण ...

-Wno-अमान्य-offsetof (सी ++ और ऑब्जेक्टिव-सी ++ केवल)

एक गैर पॉड प्रकार के मैक्रो 'offsetof' लागू करने से रोकें चेतावनी है ।

1998 आईएसओ सी ++ मानक के अनुसार, गैर-पीओडी प्रकार को 'ऑफ़सेट' लागू करने के लिए अपरिभाषित है। मौजूदा सी ++ कार्यान्वयन में, 'ऑफ़सेट' आमतौर पर कुछ गैर-पीओडी प्रकारों पर लागू होने पर भी सार्थक परिणाम देता है। इस ध्वज उन जो जानते हैं कि वे nonportable कोड लिख रहे हैं और उन जानबूझकर के लिए चुना है के लिए है (इस तरह के एक सरल 'struct' कि केवल एक निर्माता होने के आधार पर एक पॉड प्रकार होना करने में विफल रहता है।) इसके बारे में चेतावनी को अनदेखा करें।

'ऑफसेट' पर प्रतिबंध सी ++ मानक के भविष्य के संस्करण में आराम से हो सकता है।

मेरी समस्या यह है कि लगभग सभी मेरे टी प्रकारों में रचनाकार हैं, और इसलिए गैर-पीओडी के रूप में वर्गीकृत हैं। मैंने इस बिंदु को पहले अप्रासंगिक के रूप में अनदेखा किया - और निश्चित रूप से यह सिद्धांत रूप से ऑफसेट के लिए अप्रासंगिक होना चाहिए। समस्या यह है कि सी ++ मानक एक पीओडी बनाम गैर-पीओडी वर्गीकरण का उपयोग करता है, भले ही गैर-पीओडी होने के कई अलग-अलग तरीके हैं, और संकलक डिफ़ॉल्ट रूप से गैर मानक-अनुरूप उपयोग के बारे में चेतावनी देने के लिए सही है।

इस पल के लिए मेरा समाधान चेतावनी को दबाने के लिए उपरोक्त विकल्प होगा - अब मुझे यह समझने की आवश्यकता है कि इसका उपयोग करने के लिए सेमेक को कैसे बताना है।

+0

मुझे यह स्वीकार करने में दोषी लगता है - शायद मुझे इसे पूर्ववत करना चाहिए और इसके बजाय प्रश्न को हटाना चाहिए? – Steve314

+9

यह ठीक है क्योंकि यह वास्तव में आपके प्रश्न का उत्तर देता है - अन्य एक ही गलती कर सकते हैं। यहां तक ​​कि एक [बैज] भी है (http://stackoverflow.com/badges/14/self-learner) जो इसे प्रोत्साहित करता है :) –

+1

सेमेक समाधान: 'सेट (CMAKE_CXX_FLAGS "$ {CMAKE_CXX_FLAGS} -Wno-invalid-offsetof") ' – doug65536

-2

अच्छी तरह से इस विशेष त्रुटि की बेईमान व्याख्या इसे अंकित मूल्य पर लेना है: आप एक enum के अंदर से एक निजी क्षेत्र का उपयोग करते हैं। लेकिन संभवतः, enums परिभाषा द्वारा स्थैतिक हैं (मुझे लगता है कि यही कारण है कि enum स्थिरांक के साथ काम करना संभव है, वे अनिवार्य रूप से एक फैंसी नाम के साथ int स्थिरांक हैं)।

+0

enum कक्षा का सदस्य है। किसी वर्ग के सदस्यों को एक ही कक्षा के निजी सदस्यों को संदर्भित करने की अनुमति है, अन्यथा आप कभी भी किसी भी निजी सदस्य का उपयोग कैसे कर सकते हैं? यहां कोई डेटा छिपाने की समस्या नहीं है - लेकिन, ठीक है, मेरा (थोड़ा शर्मनाक) उत्तर देखें, जो कुछ मिनटों में दिखाई देना चाहिए ... – Steve314

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