2015-04-14 4 views
27

मुझे यह पता लगाने में आश्चर्य हुआ कि जीसीसी सामान्य कार्यों की बजाय वापसी प्रकार का उपयोग करते समय सरणी को वापस करने की अनुमति देता है। जैसा कि आप शायद जानते हैं कि सरणी की प्रतिलिपि नहीं बनाई जा सकती है, इसलिए यह काफी सीमित है लेकिन मुझे आपको कुछ ठंडा example दिखाएं।जीसीसी कार्य से लौटने के लिए सरणी को अनुमति देता है - बग या फीचर?

#include <iostream> 
#include <typeinfo> 

using namespace std; 

auto func() -> int [5] 
{ 
    return {4, 56, 78, 4, 0}; 
} 

int main() 
{ 
    cout << func()[2] << endl; 
    cout << typeid(func).name() << endl; 
} 

क्या यह एक कंपाइलर बग या कुछ नई सुविधा है?

दिलचस्प रूप से 'टाइपिड' रिटर्न 'FA5_ivE' जिसे 'int (()) [5]' के रूप में ध्वस्त कर दिया गया है और इसका मतलब यह है कि आप 5 इंट के फ़ंक्शन को वापस करने के लिए वास्तव में क्या सोचते हैं।

संपादित करें: मैं rvalue संदर्भ में, लेकिन किसी भी सफलता के बिना लौटे सरणी बाउंडिंग की कोशिश की (संभव रूपों में से सबसे अधिक इस्तेमाल किया):

auto &&refArrayTemp{ func() }; 

लगता है कि इस एक्सटेंशन नहीं बल्कि बेकार है।

+0

मैं वें लगता है: एक समान बग का दुरुपयोग करके हम प्रकार int const volatile() के साथ एक समारोह बना सकते हैं (क्वालिफायर अनुगामी-रिटर्न-प्रकार के निपटने से पहले scalars से छीन लिया जाता है) सरणी में एक 'स्थिर कॉन्स int [] 'एक है ... यदि ऐसा है, तो संकलक सही ढंग से व्यवहार कर रहा है। –

+1

@ बेसिलस्टारनकेविच ऐसा नहीं है; मैं 'func'' int' पैरामीटर ले सकता हूं और उन्हें लौटाए गए सरणी में रखा जाता है। – ecatmur

उत्तर

13

यह (निश्चित as of 2017-07-03) था, जो पिछला-वापसी-प्रकार के असंगत उपचार के कारण हुआ था।

सबसे पहले टिप्पणी दो प्रयास के बीच त्रुटि संदेश में अंतर एक समारोह फ़ंक्शन घोषित करने के लिए:

using Fv = void(); 
Fv f1();    // error: 'f1' declared as function returning a function 
auto f2() -> Fv;  // error: function return type cannot be function 

पहले त्रुटि, decl.c, declarators से निपटने से आता है, जबकि दूसरा आंतरिक में एक बहुत गहरा है, tree.c से, कोड उत्पन्न करने के लिए कार्य प्रकार प्रारंभ करने का प्रयास कर रहा है।

ट्रेलिंग-रिटर्न-प्रकारों को उपरोक्त त्रुटि के साथ decl.c 30 lines below में संभाला जाता है - उपरोक्त त्रुटि कोड के साथ इसे पकड़ने में बहुत देर हो चुकी है, और इसे अलग से संभाला नहीं जाता है।

सरणी के साथ, एक पीछे-वापसी-प्रकार का उपयोग करने से हमें decl.c में चेक छोड़ने की अनुमति मिलती है, अंतर यह है कि फ़ंक्शन-रिटर्निंग-सर वास्तव में जीसीसी के आंतरिक प्रतिनिधित्व के संदर्भ में मान्य है।

ध्यान दें कि आप इसके साथ बहुत कुछ नहीं कर सकते हैं;

auto a1 = func(); 
// error: invalid use of non-lvalue array 

auto& a2 = func(); 
// error: invalid initialization of non-const reference of type 'int (&)[5]' from an rvalue of type 'int [5]' 

auto&& a3 = func(); 
// error: lvalue required as unary '&' operand 

दरअसल, यहां तक ​​कि अपने कोड -Wpedantic पर अस्वीकार कर दिया गया है:: जीसीसी एक और कार्य करने के लिए func() का परिणाम गुजरती हैं, आप आवंटित करने के लिए अनुमति नहीं है संदर्भ-बाँध, क्षय या अंत में

warning: ISO C++ forbids subscripting non-lvalue array 

,

int const volatile g1();   // warning: type qualifiers ignored on function return type 
auto g2() -> int const volatile; // OK!! 
+0

कृपया इसे ठीक न करें। इसके बजाय सरणी संचालन की अनुमति दें। यदि आप करते हैं तो यह बहुत अच्छा होगा। सरणी की तरह मूल्य और प्रतिलिपि 'rvalue' संदर्भों की तरह। कोई संगतता खो जाएगी और मुझे नहीं लगता कि इसे बनाना मुश्किल होगा लेकिन यह हमारे जीवन को आसान बना देगा। – AnArrayOfFunctions

+6

@FISOCPP आप पहले से ही कर सकते हैं। 'std :: array' अंतर्निहित सी-शैली सरणी से बेहतर तरीका है। – edmz

+0

लेकिन क्यों दोनों की अनुमति नहीं है? बल्ट-इन एरे बहुत अधिक शांत दिखते हैं। – AnArrayOfFunctions

8

नवीनतम मसौदा, [dcl.array]/p10:

कार्य प्रकार सरणी या समारोह की वापसी प्रकार नहीं होगा, हालांकि वे इस तरह के लिए प्रकार सूचक या संदर्भ का एक वापसी प्रकार हो सकता है बातें। कार्यों का कोई सरणी नहीं होगा, हालांकि कार्यों के लिए पॉइंटर्स के एरे हो सकते हैं।

यह गैर-मानक जीसीसी एक्सटेंशन हो सकता है। It doesn't compile in the trunk version of clang. हालांकि, यह भी एक बग हो सकता है क्योंकि इसमें non-trailing return type के साथ असंगत व्यवहार है।

+0

तो, क्या? मेरा मतलब है, हम जानते थे कि यह कानूनी नहीं था और या तो एक बग या कुछ प्रकार का विस्तार हो सकता था। – edmz

+0

@black आप किस बात का जिक्र कर रहे हैं? – 0x499602D2

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