2014-06-11 13 views
6

मान लीजिए मैं दो स्रोत फ़ाइलें है - UndefErr.cpp:अप्रयुक्त अपरिभाषित संदर्भों को अनदेखा करने का कोई तरीका है?

#include <cstdio> 

void UndefFunc(); 
void Func2(){UndefFunc();} 

void Func1(){printf("Hi\n");} 

और main.cpp:

void Func1(); 

int main(){ 
    Func1(); 
    return 0; 
} 

आप UndefErr.cpp में देख Func2() जा रहा एक त्रुटि को ट्रिगर करने के लिए, इसके लिए अपरिभाषित UndefFunc() का उपयोग कर। हालांकि मुख्य समारोह Func2() परवाह नहीं करता है! a relevant question के अनुसार मैं एक विकल्प - अनन्य-प्रतीकों = अनदेखा-इन-ऑब्जेक्ट-फाइल लिंकर को पास कर सकता हूं, लेकिन मुझे एक अलग चीज़ चाहिए। मुझे यह जानने के लिए एक लिंकर चाहिए कि क्या अपरिभाषित कार्य कहीं भी उपयोग किए जाते हैं, और केवल तब विफल हो जाते हैं।

इस तरह के एक अजीब सवाल पूछने के लिए कारण यह है कि मैं एक lwIP उपयोग करने के लिए कोशिश कर रहा हूँ, और यह इसकी निर्भरता के सभी समझना कठिन है (मैं केवल टीसीपी/आईपी की जरूरत है), और मैं नहीं मिल सकता है इंटरनेट पर ट्यूटोरियल। तो मैंने सोचा कि मैं सबसे अधिक (या सभी) को .c फ़ाइलों को अलग से संकलित कर सकता हूं, और यह देखने के लिए कुछ सरल परीक्षण लिख सकता है कि यह क्या करता है। लेकिन यह दृष्टिकोण "अपरिभाषित संदर्भ" पर ठोकर खा रहा है, उनमें से अधिकतर शायद उपयोग के लिए अप्रासंगिक हैं।

+0

ऐसा प्रतीत होता है कि लिंकर केवल "पता लगाना" कर सकता है अगर संदर्भों को हल करने की भी आवश्यकता होती है ... एक समाधान हालांकि अगर यह बोझिल बनाने के लिए बहुत सारे फ़ंक्शन नहीं हैं तो आप उन्हें मुख्य रूप से बाहर निकाल सकते हैं। सीपीपी ... उदाहरण के लिए परियोजना में बहुत सारे कार्यों में 'UndoidFunc() {} ' – mark

+0

@mark no शून्य। और मुख्य समस्या जो मुझे नहीं पता, जो फ़ंक्शंस का उपयोग नहीं किया जाता है, यही कारण है कि मैं इसे किसी भी तरह से स्वचालित करना चाहता हूं .. –

+0

मुझे प्रश्न समझ में नहीं आता है। लिंकर शिकायत करने जा रहा है अगर यह एक अपरिभाषित समारोह का सामना करता है। –

उत्तर

4

जीसीसी 4.8.2 के साथ मैं निम्नलिखित के साथ त्रुटियों के बिना कोड लिंक करने में कामयाब । मैनुअल के अनुसार -fwhole-program, कार्यों पर static के उचित उपयोग के अनुरूप है, इसलिए अप्रयुक्त फ़ंक्शन को आउटपुट से हटा दिया जा सकता है (यानी आप संकलक को आश्वस्त करते हैं कि आपके सभी फ़ंक्शंस का उपयोग किसी अन्य कोड द्वारा नहीं किया जाएगा, संभवतः गतिशील रूप से लोड किया गया है , और आपके उपयोगकर्ताओं के लिए गारंटी देने वाला एकमात्र प्रवेश बिंदु main() है)।

मुझे -O3 जोड़ना पड़ा, मुझे यकीन नहीं है कि वास्तव में क्यों, लेकिन संकलक कार्यों का निरीक्षण करने और इसके बिना मृत कोड को समाप्त करने में बहुत रूचि नहीं रखता था।

+0

बढ़िया, मैं इस विकल्प के बारे में कभी नहीं जानता था! और हां, संकलन समय में '-O3' पारित होने के बिना, किसी कारण से लिंकर अप्रयुक्त कार्यों को रद्द करने से इंकार कर देता है। –

+1

एमएसवाईएस 2 के साथ एमएनजीडब्ल्यू जीसीसी 5.3.0 का निर्माण मैं अप्रयुक्त कार्यों को समाप्त करने में सक्षम था और इसलिए उन कार्यों के लिए "अपरिभाषित संदर्भ" त्रुटियों से बचें जिन्हें '-flto -Og' कंपाइलर विकल्पों के संदर्भ में संदर्भित किया गया है –

3

समस्या यह है कि आपका अपरिभाषित फ़ंक्शन उपयोग किया जाता है। Func2 के लिए ऑब्जेक्ट कोड उत्पन्न किया गया है, UndefFunc के लिए कोई संदर्भ नहीं है, और यह लिंकर पर जाता है। कंपाइलर को यह समझने का कोई तरीका नहीं है कि यह फ़ंक्शन हमेशा अपरिभाषित होगा क्योंकि कई अनुवाद इकाइयां हैं।

संकलन त्रुटि से बचने के लिए एक ही रास्ता लिंकर है कि आप इतना है कि यह इस मामले के लिए विधानसभा जनरेट करने का प्रयास नहीं करेंगे, अप्रयुक्त कार्यों के लिए वस्तु कोड की जरूरत नहीं है यह बताने के लिए है।

$ g++ -c main.cpp -O3 -flto 
$ g++ -c UndefErr.cpp -O3 -flto 
$ g++ main.o UndefErr.o -flto -O3 -o out 

मैं जानता हूँ कि -flto लिंकर व्यवहार कर देगा के रूप में अगर -fwhole-program पारित किया गया था और पूरी बात एक भी संकलन इकाई थी:

+1

मैंने चारों ओर खोज की है, और मुझे अभी पता चला है कि शायद मुझे दो चीजों की आवश्यकता है: प्रत्येक फंक्शन के अपने स्वयं के खंड में होने के लिए '-फडाटा-सेक्शन -फंक्शन-सेक्शन' का उपयोग ध्वज के रूप में करने के लिए करें (एक लिंकर को अनुमति देने के लिए एक वर्ग के बीच एक संदर्भ देखें), और फिर लिंकर को सटीक फ़ंक्शन (मेरे मामले में * मुख्य *) जानने की आवश्यकता है, जिसमें से संदर्भों को ट्रैक करने की आवश्यकता है। मैंने यह भी पाया कि * एलडी * में एक स्क्रिप्टिंग भाषा है, इसलिए शायद मैं यहां जाऊँगा - ऐसा लगता है कि जो भी मैं चाहता हूं उसे करने का कोई मानक तरीका नहीं है। –

+0

मुझे लगता है कि यह उल्लेखनीय है कि उपर्युक्त परिदृश्य में मुझे '_start' फ़ंक्शन से ट्रैक करना चाहिए, क्योंकि यह पहला कार्य निष्पादित किया जाना है। अन्यथा मैं एक टूटे निष्पादन योग्य के साथ खत्म हो सकता है। –

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

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