2010-05-16 26 views
25

में चेतावनी का उपयोग नहीं किया गया है मेरे पास कई सी स्रोत फ़ाइलें हैं (दोनों .c और .h फ़ाइलें)। हेडर फ़ाइलों में कई फ़ंक्शन हैं। उन कार्यों में से, केवल आंशिक रूप से किसी स्रोत में उपयोग किया जाता है। फ़ाइल। एक.h का उपयोग करें, b.h शीर्षलेख फ़ाइलें हैं और a.c और b.c .c फ़ाइलें हैं। एएच में एक.h शामिल है लेकिन केवल उन कार्यों में से कई हैं जो एक हैं। एच का उपयोग किया जाता है और बाकी का उपयोग नहीं किया जाता है।फ़ंक्शन परिभाषित किया गया है लेकिन सी

function XXXX defined but not used. 

लेकिन उन XXXX कार्य करता है जो a.c में इस्तेमाल नहीं कर रहे हैं ई.पू. में किया जाता है: संकलन के बाद मैं निम्नलिखित चेतावनी लगता है इसलिए, मैं उन कार्यों को पूरी तरह से हटा नहीं सकता हूं। इसलिए, मैंने केवल उन XXXX फ़ंक्शंस वाली एक अलग फ़ाइल बनाने का निर्णय लिया और इसे कहीं भी शामिल किया गया। इसे करने से हेडर फाइलों की कई संख्याएं बन रही हैं। क्या कोई मुझे इस समस्या को हल करने के लिए कुछ प्रभावी तरीके से सुझाव दे सकता है।

+0

यह मेरे लिए कोई समस्या नहीं है। आपके फ़ंक्शन घोषणाओं के बारे में कुछ अजीब होना चाहिए या आप कैसे संकलित कर रहे हैं। क्या आप अधिक जानकारी दे सकते हैं? – crazyscot

+2

मुझे लगता है कि हमें कुछ कोड देखने की आवश्यकता है क्योंकि यह सामान्य रूप से नहीं होता है - उदाहरण के लिए मानक शीर्षलेख देखें – Mark

+0

आप किस कंपाइलर का उपयोग कर रहे हैं? – berkay

उत्तर

57

"फ़ंक्शन परिभाषित लेकिन उपयोग नहीं किया गया" चेतावनी केवल आंतरिक लिंक के साथ फ़ंक्शंस के लिए जारी की गई है, यानी static के रूप में घोषित किए गए फ़ंक्शन। ये फ़ंक्शंस केवल एक अनुवाद इकाई में पहुंच योग्य हैं, इसलिए संकलक हमेशा जानता है कि उनका उपयोग किया जाता है (प्रोग्राम में) या नहीं। यदि आप इन कार्यों को उनके अनुवाद इकाई में संदर्भित नहीं करते हैं, तो इन कार्यों को अप्रयुक्त माना जाता है, और चेतावनी उत्पन्न होती है।

आप कह रहे हैं कि ये फ़ंक्शन "c.c में उपयोग नहीं किए जाते हैं, लेकिन बीटी में उपयोग किए जाते हैं"। यह सच नहीं है। जब आप हेडर फ़ाइल में static के रूप में किसी फ़ंक्शन को घोषित (और परिभाषित) करते हैं, तो प्रत्येक अनुवाद इकाई जिसमें हेडर फ़ाइल शामिल होती है, फ़ंक्शन के प्रति कॉपी करती है। भले ही ये कार्य बिल्कुल समान दिखते हैं, फिर भी वे अलग, पूरी तरह से स्वतंत्र कार्य हैं। तथ्य यह है कि उनके पास एक ही नाम है और एक ही कोड शामिल है, इसका मतलब कंपाइलर के लिए कुछ भी नहीं है। तो, b.c में आपको फ़ंक्शन की पूरी तरह से स्वतंत्र प्रति मिली है, जिसका उपयोग किया जाता है (जैसा कि आप कहते हैं), लेकिन a.c में पूरी तरह से स्वतंत्र प्रतिलिपि अभी भी उपयोग नहीं की जाती है।

इस मामले में प्रश्न है क्यों आप यह कर रहे हैं। पृथ्वी पर क्यों आप शीर्षलेख फ़ाइल में स्थिर फ़ंक्शन परिभाषित कर रहे हैं? अगर आपको वास्तव में ऐसा करने की ज़रूरत है (यानी।यदि आप वास्तव में प्रत्येक अनुवाद इकाई में इस फ़ंक्शन का एक अलग आंतरिक "क्लोन" बनाना चाहते हैं), तो आप कुछ कंपाइलर-विशिष्ट माध्यमों का उपयोग करके चेतावनी के आसपास काम कर सकते हैं। जीसीसी में, उदाहरण के लिए, आप __attribute__((unused)) के साथ फ़ंक्शन घोषित कर सकते हैं, इस फ़ंक्शन के लिए चेतावनी अब जारी नहीं की जाएगी।

लेकिन आम तौर पर किसी को हेडर फ़ाइल में फ़ंक्शंस को परिभाषित करने की आवश्यकता नहीं होती है। आम तौर पर बाहरी लिंकेज (यानी static) के साथ किसी फ़ंक्शन का उपयोग करने के लिए, इसे .c फ़ाइलों में से किसी एक में परिभाषित करें और हेडर फ़ाइल में घोषणा (प्रोटोटाइप) डालें। संकलक इस मामले में कोई चेतावनी जारी नहीं करेगा, भले ही फ़ंक्शन घोषित किया गया हो लेकिन कुछ अनुवाद इकाई में उपयोग न किया जाए।

+0

ऐसा करना लाइब्रेरी बनाने के लिए उपयोगी होता है जब एक फ़ंक्शन किसी दूसरे के लिए अधिक अर्थ देने के लिए अनुवाद होता है, जैसे कि 'स्थिर बूल CanHazCheezBurger() {वापसी झंडे और (हैज़चेज | हैज़बर्जर)} '। यह इसे रेखांकित करने का प्रयास है, लेकिन यह विफल रहता है क्योंकि इसमें कोई इनलाइनिंग नहीं है, केवल प्रतिलिपि बना रही है। – Leonardo

6

तुम सिर्फ चेतावनी को छिपाने के लिए चाहते हैं, का उपयोग करें:

-Wno-unused-function 

हालांकि, आप शायद सलाह caf's answer में का पालन करना चाहिए। ऐसा लगता है कि आप एक समारोह को परिभाषित कर सकते हैं जब आप केवल इसकी घोषणा जोड़ना चाहते थे।

+1

मेरी पढ़ाई से, मुझे लगता है कि ये चेतावनियां बहुत मान्य हैं और उन्हें छुपाया नहीं जाना चाहिए। मुझे लगता है कि एंड्री और कैफ सही हैं कि ओपी .h फाइलों में स्थिर कार्यों को परिभाषित कर रहा है। बस इन चेतावनियों को छुपाएं सहायक नहीं होंगे; संभावना है कि इससे सड़क के नीचे बड़ी समस्याएं पैदा होंगी। –

+0

आप सही हैं, मुझे लगता है कि उपरोक्त कैफ का उत्तर शायद सही है। http: // stackoverflow।कॉम/प्रश्न/2845748/फ़ंक्शन-डिफ़ाइंड-लेकिन-उपयोग नहीं किया गया-चेतावनी-इन-सी/2846030 # 2846030 मैंने अभी मेरा संपादन किया है। – thomasrutter

5

ऐसा लगता है कि आपकी समस्या यह है कि .h फ़ाइलों में फ़ंक्शन को परिभाषित कर रहा है। ऐसा मत करो। इसके बजाय, बस अपने घोषणाओं .h फ़ाइल में रखा, और एक मिलान .c फ़ाइल कि समारोह परिभाषाएँ शामिल है:

common.h:

#ifndef _COMMON_H 
#define _COMMON_H 

int foo(int a, int b); 

int bar(double x, double y, double z); 

#endif /* _COMMON_H */ 

common.c:

#include "common.h" 

int foo(int a, int b) 
{ 
    /* code */ 
} 

int bar(double x, double y, double z) 
{ 
    /* code */ 
} 

फिर आपके a.c और b.c sh #include "common.h" होगा, और आपको पूरे कार्यक्रम में संकलित common.c रखने की व्यवस्था करनी होगी।

4

एक और संभावना static के बजाय इन कार्यों को inline के रूप में परिभाषित करना है। इस मामले में, उन्हें हेडर में परिभाषित करने की आवश्यकता होती है ताकि परिभाषा हर जगह दिखाई दे।

कंपाइलर फ़ंक्शन का उपयोग करने वाले प्रत्येक स्थान पर कोड को रेखांकित करेगा, इसलिए सावधान रहें कि यह वही है जो आप वास्तव में चाहते हैं। इन ट्रेडऑफ की अच्छी चर्चा के साथ Here's an answer

+0

मैंने सोचा कि इनलाइन कीवर्ड केवल कंपाइलर के लिए एक सुझाव है? – Michael

6

"ऐसा न करें" के विकल्प के रूप में, निम्न पर विचार करें - कार्यों का एक सेट जो तीन अप्रयुक्त फ़ंक्शन चेतावनियों तक ट्रिगर करेगा।

static int get_version_number(void) { return 42; } 
static double hidden_global_variable(void) { return 3.14; } 
static int potential_alternative_to_macro(int x) { return 4 * x; } 

एक और समारोह, शायद हेडर फाइल के नाम पर आधारित लिखें,

static void wno_unused_myheadername(void) 
{ 
    /* don't need to actually call the functions to avoid the warnings */ 
    (void)&get_version_number; 
    (void)&hidden_global_variable; 
    (void)&potential_alternative_to_macro; 
    return; 
} 

अब हम एक अप्रयुक्त समारोह चेतावनी के लिए नीचे कर रहे हैं। यदि आप फ़ाइल में घोषित किए गए किसी भी बाहरी फ़ंक्शन में wno_unused_myheadername() को कॉल जोड़ते हैं जिसमें शीर्षलेख शामिल है, तो अप्रयुक्त फ़ंक्शन चेतावनियों का पूरा सेट गायब हो जाएगा। चूंकि वे अब सभी का उपयोग कर रहे हैं।

कंपाइलर सभी से कहीं भी अप्रयुक्त कार्यों में से कोई भी नहीं होगा, जिसमें wno_unused_myheadername शामिल है, क्योंकि यह सभी परिभाषाओं को देख सकता है और शायद यह निर्धारित कर सकता है कि wno_unused फ़ंक्शन में एकल कॉल वास्तव में कुछ भी नहीं करता है।

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

क्यों - एक अच्छा कारण बहुत से छोटे कार्यों का उपयोग करेगा जो सी 8 9 में इनलाइनिंग के लिए उपयुक्त हैं, जिसमें आपके कंपाइलर से लिंक टाइम ऑप्टिमाइज़ेशन की आवश्यकता के बिना इनलाइन कीवर्ड नहीं है।

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

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