2009-12-15 12 views
11

वर्तमान में, मैं अप्रयुक्त चर चेतावनी को दबाने के लिए निम्नलिखित समारोह टेम्पलेट का उपयोग कर रहा हूँ:सी ++ => कंपाइलर बग या कोड बग में अप्रयुक्त चर चेतावनी को दबाएं?

template<typename T> 
void 
unused(T const &) { 
    /* Do nothing. */ 
} 

हालांकि, जब लिनक्स से cygwin को पोर्टिंग, अब मैं जी ++ 3.4.4 पर संकलक त्रुटियों (हो रही है linux पर मैं 3.4 हूं .6, तो शायद यह एक बग को ठीक किया जाता है):

Write.cpp: In member function `void* Write::initReadWrite()': 
Write.cpp:516: error: invalid initialization of reference of type 'const volatile bool&' from expression of type 'volatile bool' 
../../src/common/Assert.h:27: error: in passing argument 1 of `void unused(const T&) [with T = volatile bool]' 
make[1]: *** [ARCH.cygwin/release/Write.o] Error 1 

अप्रयुक्त के लिए तर्क एक सदस्य चर घोषित किया जाता है के रूप में:

volatile bool readWriteActivated; 

वें है मेरे कोड में एक कंपाइलर बग या एक बग है?

template<typename T> 
void unused(T const &) { } 

int main() { 
    volatile bool x = false; 
    unused(!x); // type of "!x" is bool 
} 
+0

मैं समस्या को पुन: उत्पन्न नहीं कर सकता। क्या आप कोड पोस्ट कर सकते हैं जो समस्या को पुन: उत्पन्न करता है। –

+1

विलियमकेएफ - आपने एक ऐसा जवाब क्यों स्वीकार कर लिया है जिसे आप स्पष्ट रूप से बताते हैं कि आपकी समस्या का समाधान नहीं होता है? – Tom

उत्तर

2

जीसीसी में, आप एक मैक्रो इस प्रकार परिभाषित कर सकते हैं:

#ifdef UNUSED 
#elif defined(__GNUC__) 
# define UNUSED(x) UNUSED_ ## x __attribute__((unused)) 
#elif defined(__LCLINT__) 
# define UNUSED(x) /*@[email protected]*/ x 
#else 
# define UNUSED(x) x 
#endif 

कोई इस मैक्रो के साथ चिह्नित अप्रयुक्त चेतावनी जीसीसी का उत्सर्जन करता है को दबाने होगा मानकों (

यहाँ कम से कम परीक्षण का मामला है और UNUSED_ के उपसर्ग के साथ पैरामीटर का नाम बदलता है)। विजुअल स्टूडियो के लिए, आप #pragma निर्देश के साथ चेतावनियां दबा सकते हैं।

+0

हां, लेकिन यह संकलक निर्भर है। प्रश्न गैर-कंपाइलर आश्रित फैशन में ऐसा करने का सामान्य तरीका देता है, हालांकि, जैसा कि दिखाया गया है, यह कंपाइलर में एक बग का उपयोग कर रहा है। – WilliamKF

+0

+1 यह सबसे पोर्टेबल उत्तर है। भी, जीसीसी '#pragma अप्रयुक्त' का समर्थन करता है - '_Pragma' निर्देश के लिए दस्तावेज़ भी देखें। – justin

9

मुझे 100% यकीन नहीं है कि यह पोर्टेबल है, लेकिन यह मुहावरे है जिसे मैंने आमतौर पर अप्रयुक्त चर के बारे में चेतावनियों को दबाने के लिए उपयोग किया है। यहां संदर्भ एक सिग्नल हैंडलर है जिसका उपयोग केवल SIGINT और SIGTERM को पकड़ने के लिए किया जाता है, इसलिए यदि फ़ंक्शन को कभी भी बुलाया जाता है तो मुझे पता है कि प्रोग्राम से बाहर निकलने का समय है।

volatile bool app_killed = false; 
int signal_handler(int signum) 
{ 
    (void)signum; // this suppresses the warnings 
    app_killed = true; 
} 

मैं, __attribute__((unused)) साथ पैरामीटर सूची को अव्यवस्थित नापसंद करते हैं के बाद से कच्चा-टू-शून्य चाल विज़ुअल सी के लिए ++ मैक्रो का सहारा के बिना काम करता है।

+0

हां, यह कानूनी सी ++ और पोर्टेबल दोनों है। – greyfade

+1

यदि आप इस दृष्टिकोण को अप्रयुक्त() का उपयोग करने वाले मौजूदा कोड के साथ संगत बनाना चाहते हैं, तो मैक्रो को परिभाषित करें: '# डिफाईन अप्रयुक्त (एक्स) ((शून्य) x)' –

+0

यह चर नहीं होगा यदि चर का संदर्भ है एक अपूर्ण प्रकार। उदा।, 'संरचना एक; शून्य एफ (ए और ए_) {(शून्य) a_; } 'एक संकलन त्रुटि देगा। – Timothy003

28

आप वास्तव में एक पैरामीटर है एक नाम देकर इसे नहीं का उपयोग नहीं करते यह दर्शाता है की वास्तविक तरीका:

int f(int a, float) { 
    return a*2; 
} 

सभी चेतावनियों के साथ हर जगह संकलित कर देगा चालू है, अप्रयुक्त नाव के बारे में बिना किसी चेतावनी के। भले ही तर्क का प्रोटोटाइप (उदा। int f(int a, float f);) में कोई नाम हो, फिर भी यह शिकायत नहीं करेगा।

+1

+1 , यह करने का यह सही तरीका है। – Mizipzor

+7

हां, और मैं आमतौर पर अप्रयुक्त पैरामीटर और इसका अर्थ नाम देने के लिए int f (int count, float/* epsilon * /) जैसे कुछ का उपयोग करता हूं। –

+0

वास्तव में, यह अच्छा शिष्टाचार है, मैं इसे भूल गया, लेकिन आप बिल्कुल सही हैं। – haavee

1

जवाब haavee (उर द्वारा संशोधित) द्वारा प्रस्तावित एक मैं सामान्य रूप से प्रयोग करेंगे है:

int f(int a, float /*epsilon*/) { 
    return a*2; 
} 

वास्तविक समस्या तब होता है जब तर्क कभी कभी लेकिन हमेशा विधि, जैसे में उपयोग नहीं किया है:

int f(int a, float epsilon) { 
#ifdef LOGGING_ENABLED 
    LOG("f: a = %d, epsilon = %f\n", a, epsilon); 
#endif 
    return a*2; 
} 

अब, मैं पैरामीटर नाम एप्सिलॉन बाहर टिप्पणी नहीं कर सकता क्योंकि यह है कि मेरे लॉगिंग निर्माण टूट जाएगा (मैं तर्क सूची में एक और #ifdef डालने के लिए नहीं करना चाहती, क्योंकि वह कोड बहुत कठिन पढ़ने के लिए बनाता है)।

तो मुझे लगता है सबसे अच्छा समाधान टॉम के सुझाव का उपयोग करने के होगा:

int f(int a, float epsilon) { 
(void) epsilon; // suppress compiler warning for possibly unused arg 
#ifdef LOGGING_ENABLED 
    LOG("f: a = %d, epsilon = %f\n", a, epsilon); 
#endif 
    return a*2; 
} 

मेरी केवल चिंता हो सकता है कि कुछ compilers के बारे में चेतावनी हो सकता है "(शून्य) एप्सिलॉन," बयान, उदा। "कथन का कोई प्रभाव नहीं है" चेतावनी या कुछ ऐसा - मुझे लगता है कि मुझे बस उन सभी कंपाइलरों पर परीक्षण करना होगा जिनकी मुझे उपयोग करने की संभावना है ...

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