2009-08-02 10 views
25

मैं इसे बेहतर समझने के लिए कुछ टेम्पलेट कोड को डीबग करना चाहता हूं।
दुर्भाग्य से मैं टेम्पलेट metaprogramming के लिए नया हूँ और यह मुझ में पाने के लिए कठिन हैसी ++ टेम्पलेट मेटाप्रोग्रामिंग - क्या जेनरेट कोड को आउटपुट करना संभव है?

मैं उत्पादन करने के लिए preprocessed स्रोत फ़ाइलों का प्रयास करते हैं मैं कोड के 125 000 लाइनों मिलती है:।/

तो है वहाँ एक जिस तरह से मैं जेनरेट कोड देख सकता हूँ? (जिस पुस्तकालय का मैं उपयोग कर रहा हूं वह SeqAn)

+2

नहीं, लेकिन यह होना चाहिए। किसी को इसे क्लैंग प्रोजेक्ट के रूप में करना चाहिए: डी –

+0

ध्यान दें कि [SFINAE] (https://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error) के कारण जो कोड आप प्रत्येक टेम्पलेट को बस कुछ हार्ड-कोड किए गए विकल्प के साथ बदलकर प्राप्त करेंगे संभवतः अवैध होगा। जैसे जब तक इसे कभी नहीं कहा जाता है, तब तक एक टेम्पलेट वर्ग की एक विधि अच्छी तरह से उन चीज़ों को कॉल कर सकती है जो मौजूद नहीं हैं। – MvG

+1

@ जोसेफ गारविन इस समय के लिए एक क्लैंग-आधारित परियोजना है। [टेम्पलाइट, क्लैंग-आधारित टेम्पलेट इंस्टेंटेशन प्रोफाइलर और डीबगर] का नवीनतम सक्रिय संस्करण (https://github.com/mikael-s-persson/templight), [टेम्पलर विज़ुअलाइज़र] (https://github.com/ schulmar/टेम्पलर), साथ ही साथ [मेटाशेल] (https://github.com/sabel83/metashell)। –

उत्तर

21

नहीं, यह नहीं है। प्रीप्रोसेसर के पास टेम्पलेट प्रसंस्करण के साथ कुछ लेना देना नहीं है, जो संकलक द्वारा किया जाता है। टेम्पलेट्स C++ कोड उत्पन्न नहीं करते हैं, फ़ंक्शन कॉल से कहीं अधिक - वे सी ++ भाषा का एक अभिन्न हिस्सा हैं।

+0

हालांकि यह आम तौर पर सच है, यह सिद्धांत में भी प्रीप्रोसेसर के लिए सच है। अभ्यास में सबसे आसान कार्यान्वयन सी ++ उत्पन्न करना है - प्रीप्रोसेसर चरण के आउटपुट के रूप में कोड, लेकिन टेम्पलेट इंस्टॉलेशन के लिए नहीं। रिवर्स अनुचित रूप से कठिन होगा लेकिन तकनीकी रूप से असंभव नहीं होगा। मुख्य समस्या नाम लुकअप में है, और संकलक टेम्पलेट इंस्टॉलेशन के दौरान अद्वितीय नाम उत्पन्न कर सकता है। – MSalters

+0

ईमानदार होने के लिए आप अभी भी गणना के प्रकार को दिखाने के लिए डीबगर का उपयोग कर सकते हैं यदि आप इसे तुरंत चालू करते हैं। मैंने एक उदाहरण बनाया है कि विज़ुअल सी ++ का उपयोग कैसे करें। मैंने इसे अपने मेटा कार्यक्रमों के लिए अक्सर इस्तेमाल किया। – ovanes

5

यह संभवतः अपने प्रश्न का उत्तर है:

C++ Template preprocessor tool

लगता है पिछले व्यक्ति जो पूछा संतुष्ट किया है - हालांकि मैं क्यों कल्पना नहीं कर सकते! सी में एक सी ++ कंपाइलर का उत्पादन आमतौर पर काफी पढ़ा जा सकता है, क्योंकि यह समझने में सहायता नहीं है, केवल एक प्रकार की पोर्टेबल असेंबली भाषा है।

1

सामान्य रूप से पूरे कोड को आउटपुट करना संभव नहीं है। लेकिन जो मुझे बेहद दिलचस्प लगता है, वह आपको प्रकार दिखाने के लिए विजुअल सी ++ डीबगर का उपयोग करने की क्षमता है। उस साधारण मेटा-प्रोग्राम को लें:

template<class Head, class Tail> 
struct type_list 
{ 
    typedef Head head; 
    typedef Tail tail; 
}; 

struct null_type 
{}; 

template<class List> 
struct list_head 
{ 
    typedef typename List::head head; 
}; 

template<class List> 
struct list_tail 
{ 
    typedef typename List::tail tail; 
}; 

template<class List> 
struct list_length 
{ 
    static const size_t length = 1+list_length< typename list_tail<List>::tail >::length; 
}; 

template<> 
struct list_length<null_type> 
{ 
    static const size_t length = 0; 
}; 


int main() 
{ 
    typedef 
    type_list 
    < int 
    , type_list 
     < double 
     , type_list 
     < char 
     , null_type 
     > 
     > 
    >  my_types; 

    my_types test1; 

    size_t length=list_length<my_types>::length; 

    list_head<list_tail<list_tail<my_types>::tail>::tail>::head test2; 

} 

मैंने बस अपने मेटा-प्रकारों को तुरंत चालू किया। ये अभी भी खाली सी ++ वर्ग उदाहरण हैं जो कम से कम 1 बाइट लंबे हैं। अब मैं test2 के अंतिम इन्स्टेन्शियशन के बाद एक ब्रेकप्वाइंट रख दिया और देखते हैं, जो प्रकार/मूल्यों लंबाई, test1 test2 और के हैं कर सकते हैं:

यहाँ डिबगर से पता चलता है:

length 3 unsigned int 
test1 {...} type_list<int,type_list<double,type_list<char,null_type> > > 
test2 -52 'Ì' char 

अब तुम क्या आप जानते हैं सिर ने आपको एक चरित्र वापस कर दिया, आपकी सूची में int, double, char शामिल है और null_type द्वारा समाप्त किया गया है।

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

आशा है कि मदद करता है,
Ovanes

22

नहीं, सामान्य रूप में, यह नहीं किया जा सकता। टेम्पलेट्स सी ++ भाषा का हिस्सा हैं, वे एक अलग प्रीप्रोसेसर नहीं हैं, इसलिए वे सी ++ कोड उत्पन्न नहीं करते हैं।

सामान्य समाधान स्थिर कोडों और अन्य परीक्षणों के साथ अपने कोड को छिड़काव करना है ताकि यह सत्यापित किया जा सके कि सही टेम्पलेट सही तरीके से तत्काल हो जाएं।

बार जब आप अपने metaprogramming में खो जाने लगते हैं, तो इस सरल चाल में मदद कर सकते हैं कि कौन प्रकार टेम्पलेट पैरामीटर वास्तव में है:

// given a variable t of an unknown type T 
int*** i = t; 

जब संकलक इस सामना करना पड़ता है, इसे प्रिंट जाएगा एक अच्छा और सरल त्रुटि संदेश, "<long, detailed typename> को int *** में परिवर्तित नहीं कर सकता", जिससे आप आसानी से सत्यापित कर सकते हैं कि टेम्पलेट पैरामीटर टी वास्तव में वह प्रकार है जिसे आप सोचते हैं।

14

चेक my publication on C++ template metaprogram debugging

पेज 6 से आप देख सकते हैं कि यह कैसे काम करता है। विशिष्ट उद्देश्यों के लिए आपको पूरे टूलचेन की आवश्यकता नहीं होगी, इसे हाथ से किया जा सकता है।

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

हम एक ग्राफिकल फ्रंटएंड पर काम कर रहे हैं जो सभी तत्कालताओं को दिखाता है, डीबगिंग, प्रोफाइलिंग की अनुमति देता है। दुर्भाग्य से हम उस उपकरण के लिए किसी भी प्रकाशित तिथि का वादा नहीं कर सकते हैं, क्योंकि हम इसे अपने सीमित सीमित समय में करते हैं।

अद्यतन: डीबगर और प्रोफाइलर उपलब्ध है here

अद्यतन: C++Now presentation

+0

दिलचस्प लग रहा है! –

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