2012-07-01 14 views
18

में "अगर (0)" उन्मूलन को अक्षम करें यदि मैं के अंदर कोड को समाप्त करने से जीसीसी को कैसे रोक सकता हूं (0) ब्लॉक?जीसीसी

if (0) 
    do_some_debug_printing_and_checking(); 

तब, जब एक ब्रेकपाइंट मारा जाता है, मैं do_some_debug_printing_and_checking पर क्लिक करें() लाइन:

जब मैं दृश्य स्टूडियो का उपयोग, मेरे डिबगिंग तकनीकों में से एक मेरी कार्यक्रम में इस तरह कोड डाल करने के लिए है , "अगला कथन सेट करें" का चयन करें और इसे निष्पादित करने के लिए मजबूर करें।

जब मैं बैक एंड के रूप में जीसीसी/जीडीबी का उपयोग करता हूं, तो "अगला अगला कथन" अब काम नहीं करता है, क्योंकि जीसीसी बस के अंदर से कोड को हटा देता है अगर (0) कथन।

मैं निश्चित रूप से -O0 अनुकूलन अक्षम करने के लिए ध्वज का उपयोग कर रहा हूं। मैंने -fno-dce -fno-tree-dce स्पष्ट रूप से मृत कोड उन्मूलन को अक्षम करने के लिए झंडे की कोशिश की है, लेकिन इसका कोई प्रभाव नहीं है: की सामग्री यदि (0) बाइनरी फ़ाइल में मौजूद नहीं है और मैं का उपयोग नहीं कर सकते हैं इसके आगे बढ़ने के लिए अगले कथन सेट करें।

क्या को हटाने के लिए जीसीसी को बताने का कोई अच्छा तरीका है (0) सामग्री?

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

  1. यह अभी भी
  2. कोड की एक अतिरिक्त पंक्ति यह जीत लिया है:

    "अतिरिक्त चर" वैकल्पिक हल के लिए धन्यवाद, लेकिन वहाँ 2 बातें मैं इसके बारे में पसंद नहीं है कर रहे हैं रिलीज संस्करण बनाने पर स्वचालित रूप से ऑप्टिमाइज़ नहीं किया जाएगा और उन डीबग चीजों को गायब करना चाहते हैं। निश्चित रूप से मैं # ifdef-s का उपयोग कर सकता हूं, लेकिन यह और भी अतिरिक्त लाइनें है।

वास्तव में, जीसीसी को उस मृत कोड को रखने के लिए बिल्कुल कोई विकल्प नहीं है?

+1

मैं जानता हूँ कि यह नहीं है कि तुम क्या पूछ रहे थे, लेकिन कोशिश अपने आईएफएस के लिए झूठी पर वैश्विक वैरिएबल सेट का उपयोग करना। इस तरह संकलक आपके बयान को अनुकूलित नहीं करेगा। –

+12

जब आप उस फ़ंक्शन को चलाने के लिए जीडीबी में बस do_some_debug_printing_and_checking() 'कॉल नहीं करते हैं? – Mat

उत्तर

12

चेक करने के लिए सबसे आसान बात यह है कि चेक को बाहरी लिंक के साथ एक चर (कहें) पर निर्भर करता है।

उदा।

extern bool debug; 
if (debug) 
    do_some_debug_printing_and_checking(); 

नाम स्थान दायरे में कहीं न कहीं:

bool debug = false; 
+5

मैं वहां 'अस्थिर' छोड़ दूंगा। – Kos

+0

@ कोस: आप ऐसा क्यों करेंगे? –

+0

ताकि संकलक यह नहीं मान सके कि परिवर्तनीय का मान कुछ दो बिंदुओं के बीच नहीं बदलता – Kos

8

मैं यह करने के जीसीसी संकलक झंडे पर भरोसा नहीं होता। कंपाइलर झंडे जीसीसी के संस्करणों में बदल सकते हैं, और कंपाइलर्स में बदल सकते हैं। आप पा सकते हैं अपने आप को विज़ुअल सी में छह महीने में एक ही कोड डिबग करने के लिए ++ ...

@CharlesBailey कैसे एक extern चर के साथ ऐसा करने के लिए एक अच्छी सुझाव बनाता है की जरूरत है। यहां एक विकल्प है जिसके लिए एक चर को पूरे मॉड्यूल के संपर्क में आने या स्थैतिक भंडारण में रखने की आवश्यकता नहीं है।

if बयान के दायरे में एक अस्थायी चर volatile घोषित:

if (volatile bool dbg = false) 
{ 
    do_some_debug_printing_and_checking(); 
} 

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

ध्यान में रखना एक बात यह है कि चर को हमेशा ढेर पर आवंटित किया जाता है, और कार्य को बाहर होने तक ढेर पर रखा जाएगा। इस दृष्टिकोण और extern दृष्टिकोण दोनों काम करना चाहिए, लेकिन थोड़ा अलग (और शायद नगण्य) ट्रेडऑफ है।

आप इस समस्या को हल करने में मदद करने मैक्रो का उपयोग करने को तैयार हैं, तो आप आसानी से अस्थायी चर निष्क्रिय कर सकते हैं जब आपके रिलीज उत्पादन में अपने कोड:

#ifndef IS_DEBUGGING 
# define IS_DEBUGGING 0 
#endif 

#if IS_DEBUGGING 
# define TMP_DBG_FLAG volatile bool dbg_flag = false 
#else 
# define TMP_DBG_FLAG false 
#endif 

फिर अपने if बयान की घोषणा के रूप में:

if (TMP_DBG_FLAG) 
{ 
    do_some_debug_printing_and_checking(); 
} 

जब आप IS_DEBUGGING को 1 होने के लिए परिभाषित करते हैं, तो स्थानीय चर बनाया जाता है, अस्थिर घोषित किया जाता है, और रखा जाता है। जब आप IS_DEBUGGING को 0 होने के लिए परिभाषित करते हैं, तो मैक्रो निरंतर false तक फैलता है और संकलक शाखा को दूर करता है। extern दृष्टिकोण के साथ कुछ भी समान किया जा सकता है।

कोड की कुछ अतिरिक्त पंक्तियां, लेकिन वे TMP_DBG_FLAG का उपयोग करने की संख्या से स्वतंत्र हैं। कोड ifdef के टन का उपयोग करने से भी बहुत अधिक पठनीय है। मैक्रो (यह करने के लिए __LINE__ का मूल्य जोड़कर) थोड़ा सुरक्षित बनाया जा सकता है, लेकिन यह तीन मैक्रो की आवश्यकता होगी, और शायद आवश्यक नहीं है:

#if IS_DEBUGGING 
// paste symbols 'x' and 'y' together 
# define TMP_DBG_FLAG_SYMCAT0(x,y) x ## y 

// need one level of indirection to expand __LINE__... 
# define TMP_DBG_FLAG_SYMCAT(x,y) TMP_DBG_FLAG_SYMCAT0(x,y) 

# define TMP_DBG_FLAG volatile bool TMP_DBG_FLAG_SYMCAT(dbg_flag_,__LINE__) = false 
#else 
# define TMP_DBG_FLAG false 
#endif