2012-04-01 13 views
8

मुझे एक जीसीसी चेतावनी का सामना करना पड़ रहा है जिसे मैं ठीक करना चाहता हूं। असल में मैं एक विधि को स्थानीय चर के लिए एक सूचक से गुजर रहा हूं, जो मेरे मामले में बिल्कुल ठीक है। मैं समझता हूं कि संकलक मुझे क्यों बताता है कि यह एक संभावित समस्या है, लेकिन मेरे मामले में यह ठीक है।अस्थायी - कार्यवाही की आवश्यकता लेना

मैं स्थानीय स्थान पर इसे कैसे काम कर सकता हूं? संकलन करते समय -fpermissive पास करने से मुझे भविष्य की समस्याओं को खोजने में असफल हो जाएगा। मैं इस विशिष्ट समस्या को ठीक करना चाहता हूं, या इसे हल करना चाहता हूं।

कोड यहाँ उपलब्ध है:

#include <cstdio> 

class Integer{ 
public: 
    Integer(int i){ v = i; }; 
    int value(){ return v; }; 
private: 
    int v; 
}; 

int foo(Integer *i); 

int main() 
{ 
    foo(&Integer(12)); 
} 

int foo(Integer *i) 
{ 
    std::printf("Integer = %d\n", i->value()); 
} 

और संकलन मुझे देता है:

$ g++ test-reference.cpp -O test-reference 
test-reference.cpp: In function ‘int main()’: 
test-reference.cpp:15:18: error: taking address of temporary [-fpermissive] 

$ g++ --version 
g++ (Ubuntu/Linaro 4.6.3-1ubuntu3) 4.6.3 
Copyright (C) 2011 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

संपादित करें:

बनाने foo एक स्थिरांक सूचक ले, और के रूप में value() अंकन के रूप const का उपयोग करना (कॉन्स) एक ही त्रुटि देता है।

+0

@jalf चटाई प्रतिक्रिया देखते हैं, को समझने के लिए। मेरे मामले में, जब फ़ंक्शन कहा जाता है तो वेरिएबल स्कोप पर होता है। – elcuco

+1

क्या आप फ़ंक्शन के हस्ताक्षर को 'int foo (const Integer & i);'? – jrok

उत्तर

9
Integer i(12); 
foo(&i); 

इससे "अस्थायी" समस्या का पता लगाना पड़ेगा, जो आपके पास है। आप स्थानीय चर के पते को पार नहीं कर रहे हैं (जो ऊपर है, और वास्तव में इस मामले में ठीक है), आप अस्थायी पते को पकड़ रहे हैं।

जाहिर है, अगर foo उस पॉइंटर को एक या दूसरे तरीके से पकड़ने का प्रयास करता है, तो आपको लाइन के नीचे समस्याएं आती हैं।

+4

* में बदल नहीं सकते हैं * आप अस्थायी पते को पकड़ रहे हैं जो बहुत संदिग्ध है। * नहीं, यह संदिग्ध नहीं है। व्यवहार अच्छी तरह परिभाषित है, ' 12.2/3' * अस्थायी वस्तुओं को पूर्ण अभिव्यक्ति का मूल्यांकन करने के अंतिम चरण के रूप में नष्ट कर दिया गया है (लेक्सिकली) में वे बिंदु शामिल हैं जहां वे बनाए गए थे * –

+0

यह एक रावल्यू का संदर्भ लेने से कहीं अधिक खतरनाक नहीं है। – Puppy

+0

ठीक है, इसका मतलब यह नहीं था कि यह अमान्य था, बस (आईएमओ) संदिग्ध था। – Mat

3
template<typename T> const T* rvalue_address(const T& in) { 
    return &in; 
} 

मेरी राय में, यह सिर्फ कानूनी रूप में एक const T* एक const T& के रूप में लेने के लिए होना चाहिए, लेकिन यह तुच्छ समारोह handily रूपांतरण प्रदर्शन करेंगे।

+2

और अब हमारे पास कोड है कि एमएसवीसी एक चेतावनी जारी करेगा। :-) –

4

इस मामले में जीसीसी गलत है। आपका पूर्णांक एक रैल्यू है और एक रावल्यू का पता लेना अवैध है।

§5.3.1 Unary operators, Section 3

The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualified-id.

बजना इस मामले में एक त्रुटि देता है:

error: taking the address of a temporary object of type 'Integer' [-Waddress-of-temporary] 
    foo(&Integer(12)); 
     ^~~~~~~~~~~~ 
+3

जीसीसी गलत नहीं है, इसे 'त्रुटि' के साथ खारिज कर दिया गया है, क्योंकि यह अवैध है। '-fpermissive' एक जीसीसी विस्तार है जो मूल रूप से कहता है" हाँ, ठीक है, मुझे पता है कि आप क्या मतलब * *। एक्सटेंशन को जो भी गैर मानक चीजें पसंद हैं उन्हें करने की अनुमति है क्योंकि, वे गैर-मानक एक्सटेंशन हैं। – ams

+0

मानक को किसी भी बीमार गठित कार्यक्रम के लिए निदान की आवश्यकता होती है जब तक कि अन्यथा निर्दिष्ट न किया जाए। एक चेतावनी एक निदान है। भले ही जीसीसी ने * चेतावनी के बिना * एक चेतावनी * उत्सर्जित की, यह एक अनुरूपता मुद्दा नहीं होगा। –

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