2012-06-20 13 views
18

मुझे आशा है कि शीर्षक वास्तव में वर्णन करता है कि मैं पूछना चाहता था ...सी ++ विधि कॉल और प्रकार गुंजाइश संकल्प अस्पष्टता

मैं कोड है कि जीसीसी के साथ संकलित करता है तथा जैसा कि मैंने अपेक्षित तरीके से काम का एक टुकड़ा लिखा था। हालांकि, यह आईएलसी के साथ संकलित होने पर llvm के साथ संकलित नहीं होता है और कोड अलग-अलग निष्पादित करता है!

#include <iostream> 

using std::cout; using std::endl; 

class A { 
public: 
    virtual void foo() { cout << "A::foo()" << endl; } 
}; 

class B : public A { 
public: 
    typedef A base; 
    virtual void foo() { cout << "B::foo()" << endl; } 
}; 

int main() { 
    typedef B base; 
    base* bp = new B(); 
    bp->base::foo(); 
} 

जीसीसी उत्पादन:
यहाँ समस्या का एक उदाहरण है एक :: foo()
आईसीसी उत्पादन: बी :: foo()

किसी समझा सकते हैं क्या करता है मानक के बारे में कहना ये मामला?

+5

मैं कहूंगा कि यह जीसीसी और आईसीसी में एक बग है, क्योंकि 'बी :: बेस' 'बी' का _member_ नहीं है, जिसका अर्थ है कि इसे सदस्य के रूप में एक्सेस करना संभव नहीं है (' बीपी-> base')। –

+1

मैं @ जोचिमपिलबोर्ग से सहमत हूं, इसके अलावा 'आधार' को इस दायरे में बी के रूप में व्याख्या किया जा सकता है। क्या आपने चेतावनी झंडे से संकलित किया है? (- जीसीसी के लिए सभी) – Geoffroy

+1

क्या यह सिर्फ अपरिभाषित व्यवहार नहीं है, क्योंकि 'मुख्य' आवश्यक रूप का नहीं है? ऐसा लगता है कि सभी कंपाइलर्स सही हैं। –

उत्तर

7
से सी ++ 11

, §3.4.5/4:

यदि कक्षा सदस्य पहुंच में आईडी-अभिव्यक्ति फॉर्म
 
    class-name-or-namespace-name::... 
वर्ग-नाम-या-नामस्थान-नाम का योग्य-आईडी है। या -> ऑपरेटर को पहली बार ऑब्जेक्ट अभिव्यक्ति की कक्षा में देखा गया है और यदि नाम मिलता है, तो इसका उपयोग किया जाता है। अन्यथा यह पूरे पोस्टफिक्स-अभिव्यक्ति के संदर्भ में देखा गया है।

मुझे नहीं लगता कि यह स्पष्ट हो सकता है। यह B::base पाता है, इसलिए आउटपुट A::foo() होना चाहिए।

+0

मदद के लिए धन्यवाद, आप लोग बहुत ही अच्छे हैं। यह विशेष अनुच्छेद वास्तव में बहुत स्पष्ट है और वास्तव में बिंदु पर! – Nowakus

6

मुझे लगता है कि मानक के इस भाग प्रासंगिक है:

3.4.3.1 कक्षा सदस्यों [class.qual]

1) एक योग्य-आईडी के नेस्टेड-नाम-विनिर्देशक एक नामांकित करता है तो कक्षा, नेस्टेड-नेमस्सिसीयर के बाद निर्दिष्ट नाम कक्षा के दायरे (10.2), के दायरे में नीचे सूचीबद्ध मामलों को छोड़कर देखा जाता है। नाम उस वर्ग के एक या उस वर्ग के किसी भी सदस्य या उसके मूल वर्गों में से एक (क्लॉज 10) का प्रतिनिधित्व करेगा। [नोट: किसी वर्ग सदस्य को किसी संभावितबिंदु पर अपने योग्य दायरे (3.3.7) में योग्य-आईडी का उपयोग करने के लिए संदर्भित किया जा सकता है। -जेंड नोट] के अपवाद ऊपर दिए गए नाम लुकअप नियम निम्न हैं:

- एक विनाशक नाम 3.4.3 में निर्दिष्ट के रूप में देखा गया है;

- रूपांतरण-फ़ंक्शन-आईडी का रूपांतरण-प्रकार-आईडी एक वर्ग सदस्य पहुंच में रूपांतरण-प्रकार-आईडी के रूप में उसी तरह देखा जाता है (3.4.5 देखें);

- नाम टेम्पलेट-आईडी के टेम्पलेट-तर्क में संदर्भ में देखा गया है जिसमें संपूर्ण पोस्टफिक्स-अभिव्यक्ति होती है।

- एक उपयोग के लिए लुकअप उपयोग-घोषणा (7.3.3) में निर्दिष्ट क्लास या गणित नाम एक ही दायरे (3.3.10) में छिपा हुआ है।

base:: इस मामले में एक वर्ग को "नामांकित" लगता है, इसलिए कक्षा के दायरे में देखो किया जाता है। मैं नहीं देखता कि अपवाद मामलों में से कोई भी कैसे लागू हो सकता है, इसलिए यह कक्षा का दायरा है, क्योंकि baseA के बराबर है।

(5.1.1-8 इंगित करता है कि यह उस मामले में एक योग्य-आईडी है और वह 3.4.3.1 लागू होता है)

+0

सहमत हुए। यह मेरे लिए भी स्पष्ट है। कोड सही है, अच्छी तरह से परिभाषित है, और आउटपुट 'ए :: foo' होना चाहिए। –

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