2010-07-28 10 views
10

यह सरल ग फ़ाइल पर c99:unistd.h और लिनक्स

#include <unistd.h> 

void test() { 
    char string[40]; 
    gethostname(string,40); 
} 

... जब सामान्य रूप से संकलित, ठीक काम करता है:

$ cc -Wall -c -o tmp.o tmp.c 
$ 

... लेकिन जब C99 मोड में संकलित, एक चेतावनी देता है:

$ cc -Wall -std=c99 -c -o tmp.o tmp.c 
tmp.c: In function `test': 
tmp.c:5: warning: implicit declaration of function `gethostname' 
$ 

परिणामस्वरूप .o फ़ाइल ठीक है, और लिंक काम करता है। मैं सिर्फ चेतावनी से छुटकारा पाना चाहता हूं। मैं इसे अपने स्वयं के .h फ़ाइल में घोषणाओं को डालकर, एक हैकी तरीके से प्राप्त कर सकता हूं।

सी 99 के बारे में क्या है जिसका अर्थ है unistd.h में घोषणाएं शामिल नहीं हैं? सी 99 की अच्छीता को छोड़ दिए बिना, इसे दूर किया जा सकता है?

मुझे अन्य मानक libs के लिए एक ही समस्या दिखाई देती है।

उत्तर

15

आप gethostname()

man gethostname से के लिए प्रोटोटाइप पाने के लिए किसी विशेष रास्ते में कुछ मैक्रो निर्धारित करने की आवश्यकता हो सकती: glibc के लिए

फ़ीचर टेस्ट मैक्रो आवश्यकताओं (देखें feature_test_macros (7)):

gethostname(): _BSD_SOURCE || _XOPEN_SOURCE >= 500 
    sethostname(): _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500) 

तो:

#define _BSD_SOURCE 

#include <unistd.h> 

void test() { 
    char string[40]; 
    gethostname(string,40); 
} 

रक्तमय विवरण:

आप -std-c99 विकल्प निर्दिष्ट नहीं करते हैं, तो features.h (जो परोक्ष unistd.h से शामिल है) इस तरह से _BSD_SOURCE की स्थापना करने के लिए लागू हो जाएगी gethostname() के लिए प्रोटोटाइप शामिल हो जाता है कि । हालांकि, -std=c99 निर्दिष्ट करने से संकलक __STRICT_ANSI__ को स्वचालित रूप से परिभाषित करने का कारण बनता है, जो बदले में features.h_BSD_SOURCE को परिभाषित नहीं करता है, जब तक कि आप इसे अपनी खुद की सुविधा मैक्रो परिभाषा (ऊपर के रूप में) के साथ मजबूर नहीं करते।

+0

+1 बहुत अच्छी तरह से इलाज। उत्तर के लिए –

+1

+1। -10 परिभाषित करें '# परिभाषित करें _BSD_SOURCE'। कृपया निर्माण श्रृंखला में '#define _XOPEN_SOURCE 500' या बेहतर अभी तक उपयोग करें:' cc -D_XOPEN_SOURCE = 500 ... '। खैर, अगर किसी भी तरह की पोर्टेबिलिटी वांछित है। – Dummy00001

+0

लूथर के जवाब के साथ - मेरे Red Hat सिस्टम पर 'मैन gethostname' फ़ीचर टेस्ट मैक्रो आवश्यकताओं का कोई उल्लेख नहीं करता है। किसी को भी कोई विचार है क्यों? – slim

10

gethostname() मानक सी फ़ंक्शन नहीं है (यह C99 मानक में कहीं भी उल्लेख नहीं किया गया है), मानक को संकलित करते समय प्रतीक सही ढंग से परिभाषित नहीं किया गया है।

यदि आप gcc टूलचेन का उपयोग कर रहे हैं, तो -std=gnu99 का उपयोग करें और आपको वह व्यवहार मिलेगा जो आप चाहते हैं।

वैकल्पिक रूप से, <features.h> पर देखकर, ऐसा लगता है कि आप वांछित व्यवहार प्राप्त करने के लिए -D_GNU_SOURCE या -D_XOPEN_SOURCE=500 का उपयोग कर सकते हैं।

+0

हालांकि मैंने एक अलग उत्तर स्वीकार किया, '-std = gnu99' वास्तव में उपयोग किया गया फिक्स है। धन्यवाद। – slim

+0

बस इस समस्या में बस भाग गया, और '-std = gnu99' भी चुना। – Cubbi

4

man gethostname पढ़ें। यह फ़ीचर टेस्ट मैक्रो आवश्यकताओं में कहता है, कि _BSD_SOURCE (या _XOPEN_SOURCE>500) unistd.h से gethostname खींचने के लिए आवश्यक है।

अगला पढ़ें man feature_test_macros। आप पाएंगे कि -std=c99__STRICT_ANSI__ पर _BSD_SOURCE बंद कर देता है।इसका मतलब है किसे को परिभाषित करने तक आपको gethostname नहीं मिल सकता है। मैं आमतौर पर अधिकतर चीज़ों के लिए मेरी कमांड लाइन (यानी gcc -D_GNU_SOURCE -std=c99 file.c) पर _GNU_SOURCE डालता हूं, जो _BSD_SOURCE पर भी बदल जाता है।

पीएस मैनुअल पेज में एक उदाहरण प्रोग्राम है जो वर्तमान फीट-मैक्रोज़ को प्रिंट कर सकता है। आप कुछ संकलक सेटिंग्स के लिए इसे संकलित और चला सकते हैं।

+0

इनमें से कोई भी मेरे रेडहाट सिस्टम पर 'मैन गेटहोस्टनाम' में नहीं है। तुम्हारा कौन सा सिस्टम है? क्या मुझे अतिरिक्त प्रबंधन स्थापित करना चाहिए? – slim

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