2012-09-18 20 views
7

निम्नलिखित कोड मेरे लिए ठीक लग रहा है:C2070 - अवैध sizeof संकार्य

#include <stdio.h> 

    template <typename T> 
    struct A 
    { 
     static float m_kA[]; 
    }; 

    template <typename T> 
    float A<T>::m_kA[] = {1.0f, 2.0f, 3.0f}; 

    int main() 
    { 
     printf("%d\n", 
      sizeof(A<unsigned int>::m_kA)/
      sizeof(A<unsigned int>::m_kA[0])); 
     return 0; 
    } 

लेकिन जब मैं VC9 साथ संकलन मैं निम्न त्रुटि

error C2070: 'float []': illegal sizeof operand 

मिल मैं इस कोड संकलन की उम्मीद करेंगे। क्या मैं कुछ भूल रहा हूँ? क्या कोई इस अजीब व्यवहार को ठीक करने का तरीका जानता है (ध्यान दें कि टेम्पलेट के बिना सटीक वही चीज़ ठीक है और आउटपुट 3)।

ध्यान दें कि टेम्पलेट को हटाने का विकल्प एक विकल्प नहीं है, मैंने इस उदाहरण को एक कोड में पुन: उत्पन्न करने के लिए बनाया है जहां मुझे एक टेम्पलेट होने के लिए सरणी युक्त प्रकार की आवश्यकता है।

धन्यवाद

+1

एफडब्ल्यूआईडब्ल्यू, जीसीसी 4.7.1 पर ठीक संकलित: http://liveworkspace.org/code/19f48dbdb07463b08a310c168ab59a67। इसे अभी तक एक और एमएसवीसी बग या कुछ देखें। – chris

+0

मुझे नहीं लगता कि अभिव्यक्ति उस गणना की गणना कर रही है जो आपको लगता है कि यह गणना कर रहा है। – Nobody

+4

@Nobody 'sizeof array/sizeof array [0] 'एक सामान्य मुहावरे है जो सरणी की लंबाई की गणना करता है।आपको क्या लगता है कि यह गणना करता है, या आप क्या सोचते हैं कि अन्य लोग सोचते हैं कि यह गणना करता है? – hvd

उत्तर

5

http://ideone.com/3ssVi

यह जी के साथ ++ ठीक संकलित करता है।

जहां तक ​​मैं देख सकता हूँ यह इस बग से संबंधित हो सकते हैं:

http://connect.microsoft.com/VisualStudio/feedback/details/759407/can-not-get-size-of-static-array-defined-in-class-template

+0

बग की रिपोर्ट में वही समस्या दिखाई देती है जो मैं कर रहा हूं, मैं बस इसके आसपास एक रास्ता खोजने की कोशिश करूंगा – valerio

4

यह अच्छी तरह से परिभाषित किया है। ध्यान दें कि कक्षा परिभाषा में, m_kA को float[] टाइप किया गया है, जो एक अपूर्ण प्रकार है और sizeof के साथ टंडेम में उपयोग नहीं किया जा सकता है। m_kA की परिभाषा में, इसे float[3] टाइप करने के लिए पुन: घोषित किया गया है, जिसके बाद sizeof का उपयोग करना ठीक है।

10 प्रकार के सभी समायोजन के बाद (जिसके दौरान typedefs: का प्रयोग-निर्देशों और नाम स्थान उपनाम [basic.lookup.udir] (8.3.4 सरणी घोषणाओं के अर्थ को नियंत्रित करता है।)

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

3.9.2 यौगिक प्रकार [basic.compound] से

:

6 [...] एक सरणी वस्तु के घोषित प्रकार अज्ञात आकार की एक सरणी हो सकता है और इसलिए एक अधूरे हो एक अनुवाद इकाई में इंगित करें और बाद में पूरा करें; उन दो बिंदुओं पर सरणी प्रकार ("अज्ञात बाध्यता की सरणी" और "एन टी की सरणी") विभिन्न प्रकार हैं। [...]

आपके कंपाइलर मुद्दों के लिए एक समाधान एक पूर्ण प्रकार के साथ m_kA घोषित करना होगा। आकार रखने वाला एक और स्थिर सदस्य भी सहायक हो सकता है।

[मैं सी ++ 11 से उद्धरण दे रहा हूं लेकिन मेरे सर्वोत्तम ज्ञान सी ++ 03 के समान नियमों का पालन किया गया है। ]

+1

अगर सी ++ ने मुझे ऐसा करने की अनुमति दी तो मुझे प्रारंभकर्ता को इनलाइन करने में बहुत खुशी होगी। समस्या यह है कि जहां तक ​​मुझे पता है कि मैं केवल स्थानीय या वैश्विक चर के लिए ही ऐसा कर सकता हूं, और इस तरह मैं इसके लिए एक टेम्पलेट बनाने में सक्षम नहीं हूं। जैसा कि मैंने पहले कहा था कि मुझे वीसी 9 को उचित ठहराना मुश्किल लगता है, क्योंकि अगर मैं केवल टेम्पलेट को हटा देता हूं तो सबकुछ काम करता है। – valerio

+1

कुछ और सोचते हुए, [इस] (http://pastebin.com/tumC3NBU) (नोट: वैध सी ++ नहीं) एक वैध कारण है कि टाइप * चाहिए * 'फ्लोट के बजाय 'फ्लोट []' क्यों रहना चाहिए [3] 'टेम्पलेट्स के साथ। लेकिन जैसा कि हमने अब हटाई गई चर्चा में देखा है, वास्तव में प्रकार 'फ्लोट [3]' है। – hvd

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