2016-03-09 8 views
15

बजना में/LLVM 3.6.2, एक संकलन त्रुटि में निम्न कोड परिणाम जब std=c++11 साथ संकलन:क्या यह गैर-स्थैतिक सदस्य वर्ग टेम्पलेट के भीतर घनिष्ठ संरचना के 'आकार' गैर-स्थिर सदस्य प्राप्त करता है?

template <typename T=void> 
class bar 
{ 
public: 
    struct foo 
    { 
     int array[10]; 
    }; 

    int baz() 
    { 
     return sizeof(foo::array); 
    } 
}; 

int main(void) 
{ 
    bar<> b; 
    return b.baz(); 
} 

कमांड लाइन मंगलाचरण:

$ clang++ -std=c++11 nonstatic.cpp -o nonstatic 
nonstatic.cpp:12:28: error: invalid use of non-static data member 'array' 
     return sizeof(foo::array); 
         ~~~~~^~~~~ 
nonstatic.cpp:20:14: note: in instantiation of member function 
'bar<void>::baz' requested here 
    return b.baz(); 

अगर मैं bar बदल होने के लिए अब एक टेम्पलेट,

class bar 
{ 
public: 
    struct foo 
    { 
     int array[10]; 
    }; 

    int baz() 
    { 
     return sizeof(foo::array); 
    } 
}; 

int main(void) 
{ 
    bar b; 
    return b.baz(); 
} 

तब कोड साफ़ रूप से संकलित करता है। ध्यान दें, जीसीसी 5.2.1 std=c++11 के तहत दोनों संस्करणों को स्वीकार करता है। इसके अलावा, array को संलग्न क्लास टेम्पलेट बॉडी में ले जाना (लेकिन इसे टेम्पलेट के रूप में छोड़ना) इसके परिणामस्वरूप क्लैंग इसे स्वीकार कर रहा है।

मानक के साथ कौन सा व्यवहार सही है? क्या यह जीसीसी, क्लैंग, या दोनों में एक बग है?

(मैंने सीएफ-उपयोगकर्ताओं पर उसी question से पूछा, लेकिन अब तक कोई प्रतिक्रिया नहीं मिली है)।

+1

एक clang ++ बग की तरह दिखता है। पुष्टि करने के लिए गुरु की प्रतीक्षा कर रहा है। – YSC

+2

हां, निश्चित रूप से एक बग। – SergeyA

+3

वर्कअराउंड 'sizeof (((foo *) 0) -> सरणी) 'http://stackoverflow.com/questions/29359661/clang-error-invalid-use-of-non-static-data- मेम्बर में उल्लिखित' यहाँ भी। –

उत्तर

7

यह निश्चित रूप से एक क्लैंग बग है; अपने sizeof अभिव्यक्ति की संकार्य एक आईडी अभिव्यक्ति एक गैर स्थिर डेटा सदस्य को संकेतित करते है, इसलिए [expr.prim.general]/13 रखती है। यहाँ एक कम उदाहरण है:

template<class T> struct M { int f() { return sizeof(T::x); } }; 
struct S { int x; }; 
int main() { return M<S>{}.f(); } 

बग दर्शाती है जब एक निर्भर प्रकार सदस्य एक टेम्पलेट उदाहरण विधि के भीतर एक unevaluated संदर्भ में पहुँचा जा सकता है। n2253 rule enabling the use of non-static data members in unevaluated context (और बाद में सुधार) के क्लैंग का कार्यान्वयन अपेक्षाकृत कमजोर दिखाई देता है और टेम्पलेट्स के साथ बुरी तरह से बातचीत करता है; एक समान (हालांकि विशिष्ट) बग http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20151019/141535.html है।

मुझे कोई संकेत नहीं मिला है कि यह पहले से ही Clang Bugzilla पर रिपोर्ट किया गया है; आप एक नई बग खोलना चाह सकते हैं।

आपकी स्थिति के आधार पर, वर्कअराउंड में आवृत्ति विधि के बाहर स्थिर प्रकार और मूल्य गणना को स्थानांतरित करना शामिल हो सकता है; विशेष रूप से baz एक static सदस्य फ़ंक्शन भी आपके कोड को स्वीकार करने के लिए क्लैंग को मनाने के लिए पर्याप्त है।

+0

उत्तर के लिए धन्यवाद। मैं आगे बढ़ जाऊंगा और क्लैंग बगजिला के साथ एक बग फाइल करूंगा। मेरे उपयोग के मामले में टेम्पलेट पैरामीटर में से एक के (सरल) फ़ंक्शन के रूप में सरणी की लंबाई है, इसलिए मेरे लिए 'sizeof' को कॉल करने के बजाय इसका उपयोग करना बहुत आसान है। –

+2

बजना बग दायर: https://llvm.org/bugs/show_bug.cgi?id=26893 –

+1

बग तय किया गया है: https://github.com/llvm-mirror/clang/commit/e4193c5ff01b3e3ef48a2c501e07eaa88683f885 –

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