2009-02-27 12 views
114

, और __FUNCTION__ उपयोग यह मानकर कि आपके सी ++ संकलक, उन्हें समर्थन करता है, कोई विशेष कारण नहीं लॉगिंग और डीबगिंग उद्देश्यों के लिए __FILE__, __LINE__ और __FUNCTION__ उपयोग करने के लिए है?__FILE__, __LINE__ C++

मैं मुख्य रूप से अनुकूलन-या एक प्रदर्शन एक परिणाम के रूप हिट लेने का एक परिणाम के रूप में, उपयोगकर्ता को गुमराह डेटा-उदाहरण के लिए दे रही है गलत लाइन नंबर या समारोह रिपोर्टिंग के साथ संबंध रहा हूँ।

असल में, मैं भरोसा कर सकते हैं __FILE__, करने के लिए __LINE__ और __FUNCTION__ हमेशा सही काम करते हैं?

+0

__LINE__ सही काम करना चाहिए। मैंने इसे और उसके साथियों का व्यापक रूप से उपयोग किया है, जिसमें __PRETTY_FUNCTION__ शामिल है। ... लेकिन ... ठीक है, मैं अभी कोड देख रहा हूं जहां __LINE__ झूठ है। शायद क्योंकि यह प्रयास/पकड़ अपवाद हैंडलिंग के लिए कैच ब्लॉक में है। –

+2

प्रासंगिक: [पूर्वनिर्धारित मैक्रोज़ के लिए जीसीसी संदर्भ] (http://gcc.gnu.org/onlinedocs/cpp/ मानक- पूर्वनिर्धारित-Macros.html) –

उत्तर

140

__FUNCTION__ गैर मानक, __func__ सी 99/सी ++ 11 में मौजूद है। अन्य (__LINE__ और __FILE__) ठीक हैं।

यह हमेशा सही फ़ाइल और लाइन की रिपोर्ट करेगा (और यदि आप __FUNCTION__/__func__ का उपयोग करना चुनते हैं)। अनुकूलन एक गैर-कारक है क्योंकि यह एक संकलित समय मैक्रो विस्तार है; यह कभी भी किसी भी तरह से प्रभाव प्रदर्शन नहीं करेगा।

+2

'__func__' सी ++ में एक समस्या है। सी 99 डिफ़ॉल्ट तर्कों के बारे में कोई शब्द नहीं कहता है और आगे, ऐसे मामले जहां यह इतना स्पष्ट नहीं है कि '__func__' को C++ में कैसे व्यवहार करना चाहिए। – wilhelmtell

+3

@thr: जबकि आप एक अच्छा मुद्दा बनाते हैं। मैं बहुत स्पष्ट था कि '__func__' c99 में मौजूद है, सी ++ नहीं। भले ही, मुझे लगता है कि सी ++ में '__func__' का उचित कार्यान्वयन न केवल उलझन में होगा। चूंकि मैं एक कंपाइलर लेखक नहीं हूं, यह वास्तव में मेरी कॉल नहीं है। –

+0

कौन से कंपाइलर्स '__FUNCTION__' का समर्थन नहीं करते हैं? हालिया जीसीसी को छोड़कर कौन से कंपाइलर्स इसे एक चर के रूप में मानते हैं, मैक्रो नहीं? – basin

7

व्यक्तिगत रूप से, मैं कुछ भी लेकिन संदेशों डीबगिंग के लिए इन का उपयोग करने के लिए अनिच्छुक हूँ। मैंने इसे किया है, लेकिन मैं ग्राहकों या अंतिम उपयोगकर्ताओं को उस तरह की जानकारी दिखाने की कोशिश नहीं करता हूं। मेरे ग्राहक इंजीनियर नहीं हैं और कभी-कभी कंप्यूटर समझदार नहीं होते हैं। मैं इस जानकारी को कंसोल पर लॉग कर सकता हूं, लेकिन जैसा कि मैंने कहा था, अनिच्छा से डीबग बिल्ड या आंतरिक उपकरणों के लिए छोड़कर। मुझे लगता है कि यह आपके ग्राहक आधार पर निर्भर करता है, हालांकि।

+21

"मैं इस जानकारी को कंसोल पर लॉग कर सकता हूं" - या बेहतर अभी तक: इसे फ़ाइल में लॉग इन करें ताकि अगर कुछ गलत हो तो आप ग्राहक से इसे भेजने के लिए कह सकते हैं ... – Christoph

30

दुर्लभ मामलों में यह लाइन है कि कुछ और करने के लिए __LINE__ द्वारा दिया जाता है बदलने के लिए उपयोगी हो सकता है। मैंने जीएनयू कॉन्फ़िगरेशन देखा है कि कुछ परीक्षणों के लिए उचित लाइन संख्याओं की रिपोर्ट करने के लिए, मूल स्रोत फ़ाइलों में दिखाई देने वाली रेखाओं के बीच कुछ वूडू डालने के बाद। उदाहरण के लिए:

#line 100 

निम्नलिखित लाइनों __LINE__ 100 के साथ आप वैकल्पिक रूप से एक नई फ़ाइल-नाम

#line 100 "file.c" 

यह केवल शायद ही कभी उपयोगी है जोड़ सकते हैं शुरू कर देंगे। लेकिन अगर इसकी आवश्यकता है, तो मुझे कोई विकल्प नहीं है। असल में, रेखा के बजाय, एक मैक्रो का भी उपयोग किया जा सकता है जिसके परिणामस्वरूप उपर्युक्त दो रूपों में से कोई भी परिणाम हो सकता है। बढ़ावा पूर्वप्रक्रमक पुस्तकालय का उपयोग करना, आप 50 से वर्तमान पंक्ति को बढ़ा सकते हैं:

#line BOOST_PP_ADD(__LINE__, 50) 

मैंने सोचा कि यह यह उल्लेख करने के लिए उपयोगी है, जब से तुम __LINE__ और __FILE__ के उपयोग के बारे में पूछा। एक कभी नहीं हो जाता है से बाहर काफी आश्चर्य सी ++ :)

संपादित करें: @Jonathan Leffler टिप्पणी में कुछ और अच्छा उपयोग-मामले प्रदान करता है:

#line के साथ खिलवाड़ पूर्व प्रोसेसर के लिए बहुत उपयोगी है कि उपयोगकर्ता के स्रोत फ़ाइल के साथ उपयोगकर्ता के सी कोड में त्रुटियों की सूचना देना चाहते हैं। Yacc, Lex, और (मेरे लिए घर पर अधिक) ESQL/सी preprocessors ऐसा करते हैं।

22

FYI: g ++ गैर-मानक __PRETTY_FUNCTION__ मैक्रो प्रदान करता है। अभी तक मुझे सी 99 __func__ के बारे में पता नहीं था (धन्यवाद इवान!)।मुझे लगता है कि मैं अब भी __PRETTY_FUNCTION__ पसंद करता हूं जब यह अतिरिक्त कक्षा स्कोपिंग के लिए उपलब्ध होता है।

पुनश्च:

static string getScopedClassMethod(string thePrettyFunction) 
{ 
    size_t index = thePrettyFunction . find("("); 
    if (index == string::npos) 
    return thePrettyFunction; /* Degenerate case */ 

    thePrettyFunction . erase(index); 

    index = thePrettyFunction . rfind(" "); 
    if (index == string::npos) 
    return thePrettyFunction; /* Degenerate case */ 

    thePrettyFunction . erase(0, index + 1); 

    return thePrettyFunction; /* The scoped class name. */ 
} 
+0

\ _ \ _ PRETTY_FUNCTION के बारे में जानना अच्छा लगा \ _ \ _। बहुत उपयोगी! – Maverobot

4

मैं उन्हें हर समय का उपयोग करें। केवल एक चीज जिसकी मुझे चिंता है, लॉग फाइलों में आईपी दे रहा है। यदि आपके फ़ंक्शन नाम वास्तव में अच्छे हैं तो आप उजागर करने के लिए एक व्यापार रहस्य को आसान बना सकते हैं। यह डीबग प्रतीकों के साथ शिपिंग की तरह है, चीजों को खोजने के लिए और अधिक मुश्किल है। 99.9 99% मामलों में इससे कुछ बुरा नहीं होगा।

+0

लाने के लिए अच्छा बिंदु। निष्पादन योग्य से सभी स्ट्रिंग-जैसे डेटा निकालने के लिए 'स्ट्रिंग्स 'उपयोगिता का उपयोग करके इस जानकारी को निकालना मुश्किल है। यहां तक ​​कि संपीड़ित निष्पादन योग्य निकाले जा सकते हैं। आप ग्राहक साइट पर जो भी भेजते हैं उसके बारे में बहुत सावधान रहें। प्रायः प्रतिस्पर्धी अपने अधिकारियों पर हाथ पकड़ने में सक्षम होते हैं, भले ही उन्हें ऐसा करने की आवश्यकता न हो। – Marty

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