2015-12-30 4 views
10

मैं जिस कोडबेस के साथ काम करता हूं वह ऐतिहासिक रूप से प्रयास किया गया है - उद्देश्य से - stdio.h पर निर्भरता से बचने के लिए। इसमें स्वयं का प्रिंट स्वरूपण और तंत्र है, और वे हैं printf इत्यादि के बजाय क्या उपयोग किया जाना चाहिएstdio.h (या अन्य मानक शीर्षलेख) को शामिल करने से रोकें

लेकिन कोई भी इतनी बार निर्भरता जोड़ता है जिसे ध्यान में रखना और निकाला जाना है। इसलिए मैं मामलों के लिए सबसे आसान के लिए एक अलार्म करने की कोशिश की:

#if !defined(NDEBUG) 
    void printf(float dont_link_with_stdio_h); 
#endif 

जीसीसी लोग भी आसान त्रुटियों को रोकने की तर्ज पर सोच कर दिया गया है लगता है, एक उपयोगी संदेश है, क्योंकि अगर आप ऐसा करते हैं ... चाहे आपने <stdio.h> शामिल किया है या नहीं। में निर्मित समारोह 'printf'

के लिए

परस्पर विरोधी प्रकार के होते एक तरह से इस चेतावनी को बंद करने के लिए (-fno-builtin) है। और ऐसे सभी प्रकार के दृष्टिकोण हैं जो चीजों को उन चीज़ों के लिए प्रतीक डंप फ़िल्टर करते हैं, जिन्हें आप वहां नहीं रखना चाहते हैं ...

लेकिन क्या वहां एक मामूली आसान गैर-चेतावनी-कारण है (यदि आपने नहीं किया stdio.h शामिल करें) किसी को चेतावनी देने का तरीका है कि उन्होंने एक अवांछित printf उपयोग पेश किया है?

+0

क्या आप लाइब्रेरी (.lib) के संकलित संस्करण को नहीं हटा सकते हैं ताकि यह संकलित/लिंक न हो? –

+0

@LeeTaylor मैं संकलन पर्यावरण के साथ छेड़छाड़ नहीं करना चाहता, जिसका उपयोग अन्य चीजों के लिए किया जाता है जिसमें इस पुस्तकालय को शामिल किया गया है (और वे चीजें stdio.h शामिल करने के लिए स्वतंत्र हैं)। मैं जिस विधि का प्रयास कर रहा था और '-फनो-बिल्टिन' जोड़ रहा हूं, उसका उपयोग करने से कुछ कम घुसपैठ की तलाश में हूं ... उदा। कुछ ऐसा जो अकेले स्रोत के अंदर किया जा सकता है। – HostileFork

+0

'grep printf * .c'? –

उत्तर

5

साथ जाना होगा आप printf को फिर से परिभाषित कुछ बुरा मान जो एक संकलन या लिंक करने में त्रुटि का कारण होगा हो सकता है।

#define printf do_not_include_stdio_h 
#include <stdio.h> 

int main(void) { 
    printf("Hello, world!\n"); 
    return 0; 
} 

produces the output:

undefined reference to `do_not_include_stdio_h'

आप मैक्रो Munge कर सकते हैं यदि आप इसे एक और भी अधिक अस्पष्ट नाम होना चाहते हैं या अमान्य प्रतीक शामिल यदि आप चिंतित हैं उदाहरण के लिए कि कुछ गरीब आत्मा do_not_include_stdio_h परिभाषित कर दी होगी।

आप कंपाइलर झंडे में मैक्रो परिभाषा सेट कर सकते हैं ताकि आपको फ़ाइल को मैन्युअल रूप से संपादित करने की आवश्यकता न हो। उदाहरण के लिए:

gcc -Dprintf=do_not_include_stdio_h my_file.c 
2

<stdio.h> के शामिल किए जाने को रोकने के लिए, मैं

#if !defined(NDEBUG) 
#if defined(EOF) 
#error Do not include stdio.h, contact Joe for more information 
#endif 
#endif 
+1

अच्छा ... हालांकि इसके साथ समस्या यह होगी कि यह समावेशन रोक देगा यदि यह समावेशन * stdio.h के बाद * था। अगर यह हेडर पहले भी शामिल किया गया था, तो मैं इसे पसंद करना चाहूंगा ... – HostileFork

3

मैं स्रोत फ़ाइलों को बिल्कुल स्पर्श नहीं करूंगा। मैं बिल्ड स्क्रिप्ट को संशोधित करूंगा। बनाए रखने के लिए बहुत आसान है, और लोगों को प्रतिबंध को रोकने से रोकने के लिए बहुत आसान है (उदा। कोड को बदलकर जो संकलन विफल हो जाता है)।

उदाहरण के लिए, एक makefile में, आप यह सोचते हैं एक all लक्ष्य है कि सब कुछ का निर्माण किया है

all: 

    grep stdio *.h *.c 
    if ["$?" -eq 0 ]; then 
     echo "Do not use stdio. Contact Joe for info"; exit 2; 
    fi 

    <other stuff to do the build here> 

तुम भी विशेष ठिकानों पर यह कर सकते हैं। उदाहरण के लिए, यदि आपके पास कोई लक्ष्य है जो .o फ़ाइल बनाने के लिए .c फ़ाइल को संकलित करता है, तो इसे संकलित करने से पहले .c फ़ाइल को जांचें।

%.o : %.c 

     grep stdio $< 
     if ["$?" -eq 0 ]; then 
      echo "Do not use stdio. Contact Joe for info"; exit 2; 
     fi 

     $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o [email protected] 

आपका केवल समस्या अब अगर आप जो (जहां bypass.joe एक #include <stdio.h> है जैसे #include "bypass.joe" द्वारा) अपने प्रतिबंध बायपास करने के लिए निर्धारित किया जाता है कोई है क्या करना है।इसके लिए, निर्भरताओं को उत्पन्न करने के लिए टूल देखें (उदा। gcc -MM, makedepend, आदि) और अपनी स्रोत फ़ाइलों पर निर्भर सभी फ़ाइलों को खोजने के लिए एक तरीका सेट अप करने के लिए इसका उपयोग करें। अगर कोई निर्धारित है, तो अपने मेकफ़ाइल पर भी सुरक्षा सेट करें ताकि आप उन्हें संपादित कर सकें।

संपादित करें: यदि आपके पास निर्भरता फ़ाइल उत्पन्न करने के लिए एक उपकरण स्थापित है, तो बस उस फ़ाइल को stdio के लिए खोजें। यदि कोई संकलन इकाई, प्रत्यक्ष या परोक्ष रूप से, stdio.h शामिल है, तो यह निर्भरता फ़ाइल में सूचीबद्ध होगी।

+0

इस तरह grepping के साथ समस्या (मेकफ़ाइल पर आक्रामक होने से परे जो मैं एक और प्रक्रिया से उत्पन्न होते हैं) आपको चिंता है कि अगर यह किसी टिप्पणी में है, तो क्या होगा यदि यह # ifdef'd out और लागू नहीं है, आदि। कुछ तृतीय-पक्ष फ़ाइलें हैं जो .c हैं जिनके स्वयं का डीबग मोड अलग है, इसलिए वहां होगा अपवाद सूचियां, आदि होना चाहिए ... – HostileFork

+0

एक मेकफ़ाइल पर "आक्रामक" होने और किसी भी परियोजना में सभी संकलन इकाइयों (उर्फ स्रोत फ़ाइलों) पर "आक्रामक" होने का विकल्प देखते हुए, मैं पहले का चयन करूंगा। यहां तक ​​कि एक जटिल परियोजना में, मेकफ़ाइल की संख्या शायद ही कभी संकलन इकाइयों की संख्या से अधिक है। – Peter

+0

उचित बनाने के लिए, स्वचालित रूप से जेनरेट किए गए मेकफ़ाइल के भीतर कस्टम हैंडलिंग सुनिश्चित करने के लिए तकनीकें हैं, उचित विकल्प, और विकल्प के लिए धन्यवाद, अपवित्र। लेकिन मेरे विशेष मामले के लिए संतुलन में बेहतर विकल्प मेकफ़ाइल को छूना नहीं है ... – HostileFork

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