2010-12-15 19 views
31

वहाँ एक रास्ता एक टेम्पलेट समारोह के लिए संकलक instantiated कोड या सी ++ में एक वर्गहम सी ++ संकलक द्वारा कोड instantiated टेम्पलेट देख सकते हैं

मान लें मैं कोड का निम्न भाग है पता करने के लिए है

template < class T> T add(T a, T b){ 
      return a+b; 
} 

अब मैं जब फोन

add<int>(10,2); 

मैं समारोह है कि संकलक पूर्णांक विशेष संस्करण के लिए बनाता है जानना चाहूंगा।

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

आशा है कि प्रश्न स्पष्ट है। अग्रिम में धन्यवाद।

+2

क्या आप सी ++ में या असेंबली में फ़ंक्शन देखना चाहते हैं? यदि असेंबली में, 'g ++ -S' का उपयोग करें। – Job

+2

एक करीबी संबंधित प्रश्न: http://stackoverflow.com/q/4332286/57428 – sharptooth

उत्तर

17

आप निश्चित रूप से "-एस" विकल्प का उपयोग कर g ++ द्वारा उत्पन्न असेंबली कोड देख सकते हैं।

मुझे नहीं लगता कि "सी ++" समकक्ष टेम्पलेट कोड प्रदर्शित करना संभव है - लेकिन मैं अभी भी एक जी ++ डेवलपर को झुकाव करना चाहता हूं - मुझे जीसीसी की वास्तुकला क्यों नहीं पता।

असेंबली का उपयोग करते समय, आप परिणामस्वरूप कोड की समीक्षा कर सकते हैं जो आपके फ़ंक्शन जैसा दिखता है। जीसीसी एस -O1 {yourcode.cpp} चलाने का एक परिणाम के रूप में, मैं इस (AMD64, जीसीसी 4.4.4)

_Z3addIiET_S0_S0_: 
.LFB2: 
    .cfi_startproc 
    .cfi_personality 0x3,__gxx_personality_v0 
    leal (%rsi,%rdi), %eax 
    ret 
    .cfi_endproc 

कौन वास्तव में सिर्फ एक पूर्णांक अलावा (लील) है मिला है।

अब, C++ नाम मैंगलर को कैसे डीकोड करें? वहाँ एक उपयोगिता C++ filt कहा जाता है, तो आप विहित (सी-बराबर) नाम पेस्ट और आप demangled C++ बराबर

[email protected] /dev/shm $ c++filt 
_Z3addIiET_S0_S0_ 
int add<int>(int, int) 
+0

अगर लोगों को जेनरेट किए गए टेम्पलेट कोड को देखने की अनुमति दी गई थी, तो शायद यह पढ़ने के लिए बहुत अधिक होगा ... एसटीएल –

+3

अच्छी तरह से , लोगों को जेनरेटेड असेंबली को देखने की इजाजत है, यह काफी पहले से ही है, हालांकि, कभी-कभी यह वही है जो आपको मूल्यवान अंतर्दृष्टि प्राप्त करने की आवश्यकता होती है .. – qdot

+1

@qdot यह असेंबली और सी ++ जेनरेट कोड देखने के लिए बिल्कुल अलग है। कभी-कभी आप टाइपलिस्ट का उपयोग कर कक्षाओं के पदानुक्रम को उत्पन्न करना चाहते हैं तो आपको शायद अपने पदानुक्रम में सुनिश्चित होने के लिए परिणामों को सी ++ कोड के रूप में देखना होगा। असेंबली इस मामले में बिल्कुल मदद नहीं करता है। – AlexTheo

3

जेनरेटेड असेंबली का निरीक्षण करना सबसे आसान है। आप g ++ के लिए -एस ध्वज का उपयोग कर एक असेंबली स्रोत प्राप्त कर सकते हैं।

2

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

24

मिल आप विधानसभा उत्पादन को देखने के लिए चाहते हैं, इस का उपयोग करें:

g++ -S file.cpp 

g++ -fdump-tree-original file.cpp 

अपने add समारोह के लिए

01 की तरह इस वसीयत उत्पादन कुछ,:

आप कुछ (छद्म) सी ++ कोड है कि जीसीसी उत्पन्न करता देखना चाहते हैं, तो आप इस का उपयोग कर सकते

;; Function T add(const T&, const T&) [with T = int] (null) 
;; enabled by -tree-original 

return <retval> = (int) *l + (int) *r; 

1

यदि आपका तो बराबर सी ++ कोड की तलाश में नहीं (मैं पैरामीटर संदर्भ द्वारा उत्पादन थोड़ा और अधिक दिलचस्प बनाने के लिए पारित कर दिया)। संकलक इसे कभी उत्पन्न नहीं करता है। यह संकलक के लिए पहले से सी ++ उत्पन्न करने के बजाय सीधे मध्यवर्ती प्रतिनिधित्व उत्पन्न करने के लिए बहुत तेज़ है।

8

बजना (https://clang.llvm.org/) instantiated टेम्पलेट के सुंदर प्रिंट एएसटी कर सकते हैं:

अपने उदाहरण के लिए:

test.cpp

template < class T> T add(T a, T b){ 
    return a+b; 
} 

void tmp() { 
    add<int>(10,2); 
} 

कमान करने के लिए बहुत-प्रिंट एएसटी:

$ clang++ -Xclang -ast-print -fsyntax-only test.cpp 

सी लैंग-5.0 आउटपुट:

template <class T> T add(T a, T b) { 
    return a + b; 
} 
template<> int add<int>(int a, int b) { 
    return a + b; 
} 
void tmp() { 
    add<int>(10, 2); 
} 
संबंधित मुद्दे