2013-03-05 11 views
7

के 2 अलग-अलग संस्करणों पर स्रोत कोड संकलित करना मैं जीसी के विभिन्न संस्करणों का उपयोग करने वाली 2 अलग-अलग मशीनों पर अपना स्रोत कोड संकलित कर रहा हूं।जीसीसी

CFLAGS C89

-Wall -Wextra -Wunreachable-code -g -m32 -D_DEBUG -O0 -D_LARGEFILE64_SOURCE -D_REETRANT -D_THREAD_SAFE 

एक redhat-4

gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46) 
Linux 203_test_server 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:48 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux 

है और एक फेडोरा 18

gcc (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8) 
Linux localhost.localdomain 3.8.1-201.fc18.x86_64 #1 SMP Thu Feb 28 19:23:08 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux 

मेरे फेडोरा है 18 कोई त्रुटि के साथ संकलित करता है। हालांकि, redhat 4 मशीन पर मुझे कुछ त्रुटियां मिलती हैं।

channel.h:35: error: redefinition of typedef ‘channel_t’ 
internal.h:19: error: previous declaration of ‘channel_t’ was here 

मुझे लगता है कि त्रुटि सिर्फ एक परिपत्र समस्या है। हालांकि, एक ही कोड बेस के साथ 2 अलग-अलग मशीनों पर संकलन करना वास्तव में जीसीसी के 2 अलग-अलग संस्करणों का उपयोग करके एक अंतर बना सकता है?

मैं सोच रहा था कि एक कंपाइलर के एक नए संस्करण का उपयोग करने से अधिक त्रुटियां उत्पन्न हो जाएंगी, क्योंकि नया कंपाइलर अधिक सख्त हो सकता है।

यह त्रुटि हल करने का सवाल नहीं है, लेकिन संकलक पर एक सामान्य प्रश्न है।

क्या कोई झंडे मैं भविष्य में इससे बचने के लिए सेट कर सकता हूं। हो सकता है कि जीसीसी के इस संस्करण पर संकलन करते हुए ऐसा करें, यदि संस्करण संगत नहीं हैं?

+1

हां, विभिन्न कंपाइलर/संस्करण/झंडे विभिन्न परिणाम उत्पन्न कर सकते हैं, esp। 'if ifff-heavy कोड में। –

+0

जहां तक ​​'भविष्य में इससे बचने के लिए मैं किसी भी झंडे को सेट कर सकता हूं', क्या मेरा उत्तर उस कवर को कवर करता है, या आप कुछ अलग सोच रहे थे? – Mike

+0

कुछ उपयोगी जानकारी अच्छी होगी, कंपाइलर की तुलना में एक सिस्टम पर एक अतिरिक्त हेडर अलग होने की संभावना है, लेकिन आप कभी भी यह नहीं बताते कि channel.h या internal.h कहां हैं या वे कैसे शामिल हैं। आसपास के चारों ओर की रेखाएं जहां channel_t प्रकट होता है, कम से कम ifdefs के लिए भी उपयोगी होगा। आपका सीएफएलजी परिभाषित करता है कि इसके बिना बिल्कुल कुछ भी नहीं है। – technosaurus

उत्तर

4

का डुप्लिकेट है, यही कारण है कि: Why "Redefinition of typedef" error with GCC 4.3 but not GCC 4.6?

जवाब यह है कि जीसीसी इस चेक को संशोधित कर दिया गया है।

http://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=ce3765bf44e49ef0568a1ad4a0b7f807591d6412

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

अन्य वर्तमान उदाहरण है- जीसीसी 4.8 में वैडोडो ने अभी घोषणा की है। रिलीज नोट में, यह कहता है कि -Wshadow अब चेतावनी नहीं देगा अगर किसी फ़ंक्शन का नाम किसी अन्य द्वारा छायांकित होता है।

देखें: http://gcc.gnu.org/gcc-4.8/changes.html

संपादित करें: आप यह कैसे बच सकते हैं: या तो परिभाषाओं में से एक को हटा दें, या एक अलग पर ले जाते हैं फ़ाइल को शामिल करने और हटाने दोनों अन्य परिभाषाओं।

10

यह इस बात पर निर्भर करेगा कि स्रोत कोड द्वारा कौन से हेडर शामिल किए जा रहे हैं। यदि आप बाहरी पुस्तकालयों से जुड़ रहे हैं, तो हो सकता है कि आपका स्रोत कोड पुराने सिस्टम पर स्थापित लाइब्रेरी के संस्करण के साथ असंगत हो।

यदि स्रोत कोड में कोई बाहरी लाइब्रेरी शीर्षलेख शामिल नहीं है (सी लाइब्रेरी को छोड़कर) तो प्रीप्रोसेसर निर्देश हो सकते हैं जिन्हें बदलने की आवश्यकता है।

संपादित करें:

एक Google खोज के बाद, ऐसा लगता है कि channel_t कर्नेल हेडर से है। आप दो मशीनों पर कहीं अलग कर्नेल रिलीज का उपयोग कर रहे हैं। यदि कोड कर्नेल हेडर फ़ाइल पर निर्भर करता है, तो इसे Red Hat मशीन के मुकाबले कर्नेल संस्करण की आवश्यकता हो सकती है। आपने यह निर्दिष्ट नहीं किया है कि कोड क्या है (क्या यह एक डिवाइस ड्राइवर है?), या इसमें कौन सी फाइलें शामिल हैं, इसलिए अधिक कहना मुश्किल है।

+0

आप उत्तर अच्छे हैं, इसलिए +1 आपको 'अच्छा' टैग देता है .. –

+0

@GrijeshChauhan: धन्यवाद! – teppic

4

दो प्रणालियों पर channel.h और internal.h की सामग्री की तुलना करें जहां आपको अलग-अलग परिणाम मिल रहे हैं। मुझे संदेह है कि मुद्दा जीसीसी का संस्करण है। यह अधिक संभावना है कि त्रुटियां समय के साथ उन फ़ाइलों में कोड परिवर्तनों का परिणाम हैं, जैसे कि जब एक सिस्टम में लाइब्रेरी का एक नया संस्करण होता है और दूसरे की तुलना में संबंधित हेडर फाइलें होती हैं।

1

शुरुआत के लिए, चलो अपनी समस्या के बारे में बात करते हैं। मुझे लगता है कि आपके सिस्टम का सबसे संभावित कारण दूसरे सिस्टम पर एक सिस्टम पर त्रुटियां दे रहा है, यह कोड समान नहीं है; आप अपने कोड बेस में आने वाले सूक्ष्म परिवर्तनों को देखने के लिए कुछ टूल या diff कमांड के माध्यम से इसे सत्यापित करना चाहेंगे।स्रोत फ़ाइल में

typedef struct Foo 
{ 
    int bar; 
} *Fooptr; 

:

typedef struct Foo* Fooptr; 

एक हेडर फाइल में और उसके बाद: त्रुटि प्रकार के साथ आम तौर पर जब मैंने देखा है की समस्याओं, आप की तरह कुछ है। जिसका अर्थ है कि आप स्रोत में टाइपिफ़ को छोड़ सकते हैं और यह ठीक होना चाहिए। बस कुछ देखने के लिए।

अब अगर यह एक gcc मुद्दा है, को हल करने के लिए अपने समस्या है, यह have multiple versions of gcc on the same computer संभव है और फिर -v विकल्प के माध्यम से साथ चलने के लिए gcc का सही संस्करण निर्दिष्ट करने के लिए दूसरा विकल्प है। इसलिए 4.1.2 को अपने फेडोरा 18 मशीन पर एक शॉट देने का अच्छा विचार हो सकता है।

एक और ध्यान दें, यदि आप -v विकल्प का उपयोग, लेकिन चलाने के लिए gcc का एक संस्करण निर्दिष्ट नहीं करते हैं, तो आप (stderr उत्पादन पर) आदेशों संकलन के चरणों को चलाने के लिए मार डाला मिल जाएगा। यह देखने के लिए उपयोगी हो सकता है कि क्या हो रहा है और यदि प्रत्येक मशीन पर क्या हो रहा है के बीच कोई बड़ा अंतर है।


ठीक है, अब आपके प्रश्नों पर। हां, gcc: के "संस्करण एक्स" पर संकलन के लिए झंडे हैं, शुरुआत के लिए __VERSION__ Predefined Macro है, यह आपको संस्करण संख्या के const char * पर वापस थूक देगा। यह काफी उपयोगी हो सकता है, लेकिन जीसीसी प्रलेखन के रूप में कहा गया है:

आप इसकी सामग्री किसी विशेष रूप होने पर निर्भर नहीं होना चाहिए, लेकिन यह रिलीज संख्या

कम से कम शामिल करने के लिए पर गिना जा सकता है इसके बावजूद, मैंने आमतौर पर आउटपुट का केवल 1 रूप देखा है जो "4.6.3" जैसा है यदि gcc का मेरा संस्करण 4.6.3-1ubuntu5 है।

अब यदि आप जानते हैं (या संदिग्ध) है कि अपने कोड के कुछ gcc का एक विशेष संस्करण का कारण होगा आप अपने आप को "रक्षा" के लिए __GNUC__, __GNUC_MINOR__, और __GNUC_PATCHLEVEL__ पूर्व-निर्धारित मैक्रो का उपयोग कर सकते करने के लिए त्रुटियों का कारण:
यहाँ एक है लघु स्निप-यह उच्चतम स्तर पर दिखा कि यह कैसे उपयोग करने के लिए:

#if __GNC__ == 3 
    printf(“Hello version 3.x.x\n”); 
#elif __GNC__ == 4 
    printf(“Hello version 4.x.x\n”); 
#endif 

तो ऊपर प्रणाली है जहाँ संस्करण 4.6.3 आप "नमस्ते संस्करण 4.xx" संदेश दिखाई होता है पर। तो फिर तुम और अधिक उन्नत हो और subversions जांच करके यह भी कर सकते हैं:

#if __GNUC__ > 3 || \ 
    (__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \ 
     (__GNUC_MINOR__ == 2 && \ 
      __GNUC_PATCHLEVEL__ > 0)) 
    printf(“I’m a gcc greater than 3.2.0\n”); 
#endif 

या कि अपनी खुद की मैक्रो का उपयोग करने का क्लीनर संस्करण:

#define GCC_VERSION (__GNUC__ * 10000 \ 
    + __GNUC_MINOR__ * 100 \ 
    + __GNUC_PATCHLEVEL__) 
#if GCC_VERSION > 30200 
    printf(“I’m a gcc greater than 3.2.0\n”); 
#endif 

के विभिन्न संस्करणों अगर के बारे में आपके प्रश्न को हल करने के लिए gcc विभिन्न त्रुटियों का उत्पादन करेगा, आप सही हैं कि gcc की प्रत्येक रिलीज में और भी चल रहा है और कभी-कभी चीजें बदलती हैं ताकि आप कंपाइलर के विभिन्न संस्करणों के बीच अंतर देखेंगे। सबसे अच्छा शर्त यह है कि आप दोनों के बीच प्रत्येक संस्करण के लिए रिलीज नोट्स को जांचना है। (4.1 से 4.7 तक)।

मैं सुनिश्चित नहीं हूं आपके पास कौन सा लक्ष्य आर्किटेक्चर है, इसलिए सुनिश्चित करें कि आप प्रत्येक दस्तावेज़ में उन विशिष्ट अनुभागों की जांच करें। लेकिन मुझे लगता है कि आप वास्तव में "Build system improvements" और "Incompatible changes to the build system" पर एक नज़र रखना चाहते हैं, वे सी कोड के लिए विशिष्ट अनुभाग भी बनाते हैं जो समीक्षा के लिए आसान हो सकता है।

1

यह कहने के लिए यहां पर्याप्त जानकारी नहीं है कि क्या हो रहा है। मैं उन लोगों के साथ शामिल हूं जो कहते हैं कि यह एक कंपाइलर संस्करण समस्या होने की संभावना नहीं है।

यह त्रुटि होती है (जाहिर है) जब संकलक एक ही नाम के लिए दो अलग-अलग घोषणाओं का सामना करता है। यह पता लगाना मुश्किल नहीं होना चाहिए कि यह क्यों हो रहा है।

internal.h और channel.h हेडर फ़ाइलों को संदर्भित करने के लिए मेकफ़ाइल देखें। उद्धृत लाइनों में typedef या channel_t के लिए अन्य घोषणा होगी। सुराग के लिए इन घोषणाओं से बाहर काम करें।

मुझे यह मानना ​​चाहिए कि इनमें से एक या दोनों फाइलें पुस्तकालयों में हैं जिनका आप उपयोग कर रहे हैं। यदि internal.h और channel.h दोनों अपना स्वयं का कोड हैं, तो अपना खुद का कोड डीबग करें!

अन्यथा कई संभावनाएं हैं। सबसे अधिक संभावना है ताकि कई घोषणाओं सशर्त संकलित किया जा रहा है जब केवल एक होना चाहिए

  1. प्रीप्रोसेसर -D या #define एड झंडे सही नहीं हैं।

  2. दो अलग-अलग पुस्तकालयों या अन्य मानक शीर्षलेखों और पुस्तकालय का नाम संघर्ष है।

  3. आपके स्वयं के कोड में एक लाइब्रेरी या मानक शीर्षलेख के साथ संघर्ष है। यदि channel_t एक प्रकार है जिसे आपने परिभाषित किया है, तो यह एक समस्या है। आपको _t में समाप्त होने वाले अपने प्रकार को परिभाषित नहीं करना चाहिए क्योंकि ये कार्यान्वयन के लिए आरक्षित हैं।

उपरोक्त संख्या 1 कई तरीकों से हो सकता है, लेकिन सबसे आम पुस्तकालय की गलत कॉन्फ़िगरेशन है। ओएस के लिए लाइब्रेरी आमतौर पर ./configure एड होना चाहिए जिसका उपयोग किया जा रहा है। यदि आप एक लिनक्स में कॉन्फ़िगर करते हैं और दूसरी प्रतिलिपि बनाते हैं, तो आप जो भी देख रहे हैं उसकी तरह आप समस्याओं की मांग कर रहे हैं।

संख्या 2 एक लिनक्स पर हो सकता है और अन्य लाइब्रेरी संस्करण मतभेदों के कारण नहीं हो सकता है। इस मामले में, त्रुटि के बिना मशीन को उसी संस्करण में त्रुटि के साथ मशीन अपडेट करें। ./configure चलाने के लिए मत भूलना।

नंबर 3 के लिए फिक्स स्पष्ट है। अपना प्रकार का नाम बदलें।

मुझे टोर में channel.h और channel_t दिखाई देता है।मेरा जंगली अनुमान यह है कि आप टोर का उपयोग कर रहे हैं और त्रुटि के साथ मशीन पर टोर गलत कॉन्फ़िगरेशन देख रहे हैं।

1

यह त्रुटि हल करने का कोई प्रश्न नहीं है, लेकिन कंपाइलर्स पर एक सामान्य प्रश्न है।

क्या कोई झंडे मैं भविष्य में इससे बचने के लिए सेट कर सकता हूं।

एक संकलक से प्रत्येक विशेष संस्करण का अपना स्विच या झंडे के साथ आ जाएगा।

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

यदि कंपाइलर संस्करण, हालिया या भविष्य संस्करण, आप का उपयोग कर रहे हैं, तो आपके स्रोत कोड पर कुछ चेक से बचने/छोड़ने के लिए स्विच को स्वीकार/स्वीकार नहीं किया गया है, तो इससे बचने का कोई तरीका नहीं है।