8

यहां एक अपरिभाषित विधि वाला एक वर्ग है। ऐसा लगता है compilers इतने लंबे समय के रूप में अपरिभाषित सदस्य समारोह कभी नहीं कहा जाता है, इस वर्ग के उदाहरण का निर्माण करने की अनुमति:क्या सभी अप्रयुक्त अपरिभाषित तरीकों की अनुमति है?

struct A { 
    void foo(); 
}; 

int main() { 
    A a;  // <-- Works in both VC2013 and g++ 
    a.foo(); // <-- Error in both VC2013 and g++ 
} 

यहाँ एक ऐसी ही स्थिति है, लेकिन एक है कि विरासत शामिल है। सबक्लास Bar बेस क्लास Foo बढ़ाता है। Foo एक विधि g() परिभाषित करता है। Bar समान नाम वाले विधि वाणी लेकिन यह परिभाषित नहीं करता:

#include <iostream> 

struct Foo { 
    void g() { std::cout << "g\n"; } 
}; 

struct Bar : Foo { 
    void g(); 
}; 

int main() { 
    Bar b;  // Works in both VC2013 and g++ 
    b.Foo::g(); // Works in both VC2013 and g++ 
    b.g();  // Error in both VC2013 and g++ 
} 

यहाँ से ऊपर का एक परिवर्तन हो। यहां फर्क सिर्फ इतना है कि g()Foo और Bar दोनों को virtual है:

#include <iostream> 

struct Foo { 
    virtual void g() { std::cout << "g\n"; } 
}; 

struct Bar : Foo { 
    virtual void g(); 
}; 

int main() { 
    Bar b;  // Works in g++. But not in VC2013, which gives 
       // 'fatal error LNK1120: 1 unresolved externals' 

    b.Foo::g(); // Works in g++, but VC2013 already failed on b's construction 
    b.g();  // Error in g++, but VC2013 already failed on b's construction 
} 

VC2013 और जी के बीच ++ अलग व्यवहार के विपरीत के लिए कोड टिप्पणी देखें।

  1. कौन सा कंपाइलर सही है, यदि कोई है?
  2. वीसी2013 के कंपाइलर के पास virtual कीवर्ड के साथ अपने संस्करण में virtual कीवर्ड के बिना किसी संस्करण की तुलना में कुछ अलग-अलग शिकायतें क्यों हैं?
  3. अप्रयुक्त अपरिभाषित विधियों को हमेशा अनुमति दी जाती है? यदि नहीं, तो वे सभी मामले क्या हैं जिनमें वे की अनुमति नहीं है?
  4. Barg() की घोषणा ओवरराइडिंग के रूप में गिनती है, भले ही Bar परिभाषा प्रदान नहीं करता है?
+0

vtable को कन्स्ट्रक्टर में संदर्भित किया गया है, और इसे वर्चुअल फ़ंक्शंस के पते की आवश्यकता है, इसलिए VC2013 की त्रुटि उचित लगती है। – BartoszKP

उत्तर

8

कौन सा कंपाइलर सही है, यदि कोई है?

वे दोनों सही हैं। आपका कोड गलत है, कोई डायग्नोस्टिक आवश्यक नहीं है। [Class.virtual]/11

एक आभासी समारोह एक वर्ग में घोषित परिभाषित किया जाएगा, या उस वर्ग में शुद्ध (10.4) घोषित, या दोनों; लेकिन (3.2) की कोई डायग्नोस्टिक आवश्यक नहीं है।

[intro.compliance]/2:

एक कार्यक्रम एक नियम के उल्लंघन हो, तो जो कोई निदान के लिए आवश्यक है, इस अंतर्राष्ट्रीय मानक स्थानों कोई कार्यान्वयन पर कि के संबंध में आवश्यकता है कार्यक्रम।

जीसीसी के लिए अपनी अनुकूलन सेटिंग्स पर नज़र डालें, वे व्यवहार को प्रभावित कर सकते हैं।


अप्रयुक्त अपरिभाषित तरीकों हमेशा की अनुमति है?

एक सदस्य फ़ंक्शन को परिभाषित किया जाना चाहिए यदि केवल और यदि यह odr-used है। [Basic.def।ओडीआर]/3:

हर कार्यक्रम हर गैर इनलाइन समारोह या चर ओडीआर से इस्तेमाल किया है कि कार्यक्रम में है कि के ठीक एक परिभाषा शामिल होगा; कोई निदान आवश्यक है।

अब [basic.def.odr]/2 पर विचार करें:

कोई व्यंजक संभावित मूल्यांकन किया जाता है जब तक कि किसी unevaluated संकार्य (खण्ड 5) या उसके उपसूचक है।
[...]
यदि वर्चुअल सदस्य फ़ंक्शन ओआरडी-प्रयुक्त होता है तो यह शुद्ध नहीं होता है।
एक गैर-ओवरलोडेड फ़ंक्शन जिसका नाम संभावित रूप से मूल्यांकन की गई अभिव्यक्ति या उम्मीदवार फ़ंक्शंस के सेट के सदस्य के रूप में प्रकट होता है, यदि संभावित रूप से मूल्यांकन की गई अभिव्यक्ति से संदर्भित होने पर ओवरलोड रिज़ॉल्यूशन द्वारा चुना गया है, तो यह ओडीआर-प्रयुक्त होता है, जब तक कि यह एक न हो शुद्ध वर्चुअल फ़ंक्शन और इसका नाम स्पष्ट रूप से योग्य नहीं है।

तुम अब भी decltype या sizeof अंदर अपरिभाषित गैर आभासी सदस्य कार्यों का उपयोग करने की अनुमति है। लेकिन गैर शुद्ध वर्चुअल फ़ंक्शंस केवल ओडीआर-प्रयुक्त होते हैं क्योंकि वे शुद्ध नहीं होते हैं।


जी के क्या बार की घोषणा() अधिभावी भी जब बार एक परिभाषा प्रदान नहीं करता है के रूप में गिनती?

हां।

+0

, 'वे दोनों सही हैं', क्या आपका मतलब है कि जी ++ के लिए सफलतापूर्वक 'बी' (जिसका वर्ग वर्चुअल विधि है) का निर्माण करना ठीक है, जबकि वीसी2013 नहीं कर सकता है, क्योंकि यह अनिर्दिष्ट व्यवहार है? – CodeBricks

+1

@CodeBricks यह अपरिभाषित व्यवहार के लिए काफी समान है। [यह उत्तर] जांचें (http://stackoverflow.com/questions/22180312/difference-between-undefined-behavior-and-ill-formed-no-diagnostic-message-requ)। – Columbo

+0

क्या इसका मतलब है कि गैर-शुद्ध वर्चुअल फ़ंक्शन को ओडीआर-प्रयुक्त होने के लिए नहीं कहा जाना चाहिए? – CodeBricks

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