2011-10-04 10 views
8

जब मैं __FUNCTION__ मैक्रो/वेरिएबल का उपयोग डीबगिंग जानकारी मुद्रित करने के लिए करता हूं, तो माइक्रोसॉफ्ट सी ++ कंपाइलर और जीसीसी का उपयोग करते समय यह आउटपुट में क्या अंतर होता है। उदाहरण के लिए, निम्नलिखित तुच्छ कोड का उपयोग:मैं जीसीसी का उपयोग कर __FUNCTION__ के माइक्रोसॉफ्ट संस्करण की नकल कैसे करूं?

class Foo 
{ 
    public: 
     void Bar(int a, int b, int c) 
     { 
      printf ("__FUNCTION__ = %s\n", __FUNCTION__); 
     } 
}; 

int main (void) 
{ 
    Foo MyFoo; 

    MyFoo.Bar(); 

    return 0; 
} 

माइक्रोसॉफ्ट विजुअल C++ संकलक का उपयोग करना, मैं

__FUNCTION__ = Foo::Bar 

पाने जबकि जब जीसीसी का उपयोग कर (Mac पर इस मामले में) संकलन, मैं

मिल
__FUNCTION__ = Bar 

दूसरे उदाहरण आदर्श नहीं है, क्योंकि मैं अक्सर साथ, कहते हैं, Init() और Uninit() तरीकों और एक डिबग आउटपुट में अपनी वर्चुआ का पता लगाने के कई वर्गों है यह कहना असंभव है कि इनमें से कौन सा वर्ग नाम के रूप में बुलाया गया है, गायब हो जाएगा। अब, मुझे पता है तुम __FUNCTION__ के स्थान पर __PRETTY_FUNCTION__ उपयोग कर सकते हैं की तरह

__PRETTY_FUNCTION__ = void Foo::Bar(int, int, int) 

कौन सा ठीक है, लेकिन मैं क्या जरूरत के लिए अपने एक सा भी वर्बोज़ और मानकों का एक बहुत कुछ के साथ कार्यों के लिए लंबे समय से एक सा हो जाता है कुछ पाने के लिए ।

तो मेरा प्रश्न है (आखिरकार), आउटपुट को जीसीसी का उपयोग करके Foo::Bar की तरह दिखने का कोई तरीका है, जैसा उपरोक्त उदाहरण में है?

static const char __func__[] = "function-name "; 

उदाहरण::

#include <iostream> 

namespace meh { 
    void foobar() { std::cout << __func__ << std::endl; } 
}; 

struct Frob { 
    void foobar() { std::cout << __func__ << std::endl; } 
    static void barfoo() { std::cout << __func__ << std::endl; } 
}; 

int main() { 
    std::cout << __func__ << std::endl; 
    meh::foobar(); 
    Frob().foobar(); 
    Frob::barfoo(); 
} 

हालांकि, जी के साथ ++ उत्पादन:

main 
foobar 
foobar 
barfoo 

हालांकि, कि है

+0

मैं उत्सुक के रूप में मैं इस मैक्रो की जरूरत कभी नहीं किया है कर रहा हूँ के समान है, यही कारण है कि आप इसे ज़रूरत है? क्या आपका कंपाइलर/टेस्ट सूट/मेमोरी चेकर आपको कोड की सटीक रेखा नहीं बताता है जहां समस्या होती है? - अगर यह लॉगिंग के लिए है तो मैं लिखने वाले लॉग का सुझाव देता हूं जो कि समान होगा, कंपेलर का कोई फर्क नहीं पड़ता - इसके लिए आप लॉग का विश्लेषण करने के लिए पैटर्न मिलान टूल लिख सकते हैं। – Tom

+0

संभावित डुप्लिकेट [__PRETTY_FUNCTION__, __FUNCTION__, __func__ के बीच क्या अंतर है?] (http://stackoverflow.com/questions/4384765/whats-the-difference-between-pretty-function-function-func) –

+0

डुप्लीकेट नहीं - उस प्रश्न के बारे में कुछ भी कहना नहीं है कि माइक्रोसॉफ्ट शैली कैसे प्राप्त करें जीसीसी से बाहर स्ट्रिंग। –

उत्तर

3

यदि आप इसे ट्रेसिंग के लिए उपयोग कर रहे हैं, तो आप हमेशा typeid(T).name() का उपयोग कर सकते हैं और केवल सशर्त रूप से प्रति प्लेटफ़ॉर्म संकलित कर सकते हैं। निश्चित रूप से मैक्रो के रूप में सुविधाजनक नहीं है, लेकिन यह काम कर सकता है।

थोड़ा __CLASS__ macro in C++

+0

जीसीसी [डेमंगलिंग लाइब्रेरी] (http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html) के साथ इस मार्ग पर जाकर काम में आ सकता है। – user786653

2

समारोह के नाम मानक द्वारा मंजूर इस प्रकार परिभाषित किया गया है वैध सी ++ व्यवहार:

§ 8.4.1, 8: फ़ंक्शन-स्थानीय पूर्वनिर्धारित चर __func__ को परिभाषित किया गया है कि static const char __func__[] = "function-name "; फ़ॉर्म की परिभाषा प्रदान की गई थी, जहां फ़ंक्शन-नाम कार्यान्वयन-परिभाषित स्ट्रिंग है। यह निर्दिष्ट नहीं है कि इस तरह के चर के पास प्रोग्राम

आईई में किसी अन्य ऑब्जेक्ट से अलग पता है या नहीं, तो आप इसके मूल्य पर भरोसा नहीं कर सकते हैं। यदि आप गैर-पोर्टेबल एक्सटेंशन का उपयोग करना चाहते हैं, तो एक समान प्रश्न देखें: What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?

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