2011-10-10 16 views
13

के आस-पास एक बाहरी "सी" का उपयोग क्यों करें कुछ दिन पहले, मैं सी ++ कोड के इस टुकड़े में आया था, हालांकि मैं कोड को पेस्ट नहीं कर सकता, मैं कुछ नमूना कोड के साथ समस्या को फिर से बना सकता हूं। पहले, फ़ाइल, namespace.h:सी ++ नेमस्पेस

#include <iostream> 
using namespace std; 

namespace useless{ 
    class X { 
    int m_myint; 
    static X *m_foobar; 
    X* getPrivVal(void); 
    public: 
    int getMember(void); 
    X* getStaticVal(void); 
    }; 
} 

इसके बाद, namespace.cpp:

#include "namespace.h" 

extern "C"{ 
    namespace useless{ 
    X* X::m_foobar = NULL; 
    X* X::getPrivVal(void){ 
     if(m_foobar == NULL) 
      m_foobar = new X; 
     return(m_foobar); 
    } 
    } 
} 

namespace useless { 
    int X::getMember(void){ 
     if(m_myint == 0) 
      m_myint = 1; 
     return(m_myint); 
    } 
    X* X::getStaticVal(void){ 
     return(getPrivVal()); 
    } 
} 

using namespace useless; 

int main(void){ 
    X y; 
    cout << "The int value is " << y.getMember() << endl; 
    cout << "The value of the static member is " << y.getStaticVal() << endl; 
    return(0); 
} 

इस कोड को संकलित और ठीक से जुड़ा हुआ है जब मैं जी ++ 3.4.3 इस्तेमाल किया, लेकिन निम्न त्रुटि जब मैं का उपयोग देता है जी ++ 4.x, मैंने जीसीसी 4.6.1 के साथ-साथ जीसीसी 4.2.1 के साथ प्रयास किया है। लिनक्स के साथ ही मैक, एक ही परिणाम पर कोशिश की है।

यह त्रुटि (Suse के लिए) है:

g++ -o namespace namespace.cpp 
namespace.h:8:15: error: previous declaration of useless::X* 
    useless::X::m_foobar with C++ linkage 
namespace.cpp:5:11: error: conflicts with new declaration with C linkage 

कोई क्या विरासत सी ++ कोड काम करना चाहते थे पर कुछ प्रकाश डाला कृपया, यह एक हैक या वैकल्पिक हल हो सकता था एक पुरानी समस्या से बचने के लिए कि अब मुझे पता नहीं है। ओह, वैसे, extern "C" के अंदर की विधि को सी ++ कोड द्वारा बुलाया जाता है और कोई भी सी कोड नहीं जिसे मैंने शुरू में संदेह किया था। एफवाईआई, यह अब विरासत कोड है, 2001/2002 अवधि में लिखा गया हो सकता है।


धन्यवाद दोस्तों। मैं आगे बढ़ गया हूं और बिना किसी बड़े प्रभाव के बाहरी "सी" से छुटकारा पा लिया हूं। @ बजेर्न पोलेक्स: वह व्यक्ति जिसने कोड लिखा था वह लंबे समय से चला गया है।

+6

यदि यह कोड संस्करण-नियंत्रित है, तो जो भी लिखा है उसे ढूंढने के लिए इतिहास की जांच करें, और जब तक वे अपने पापों को पश्चाताप न करें तब तक उन्हें छड़ी से मारा। –

उत्तर

6

सी ++ नाम मैंगलिंग बुद्धिमान चर उत्पन्न करने के प्रयास की तरह लगता है। यह extern "C" का उपयोग करने का एक हिस्सा है।

नया कंपाइलर स्पष्ट रूप से महसूस करता है कि यह वास्तव में काम नहीं करता है।

2

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

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

+3

जब आप सी ++ के बारे में बात कर रहे हों तो नाम मैंगलिंग को बंद करना समझ में नहीं आता है - कक्षाओं और नामस्थानों जैसी विशेष विशेषताएं। –

14

extern "C" निर्देश के दो प्रभाव हैं, यह संभव होने पर मैंगलिंग अक्षम करता है और सी कॉलिंग सम्मेलन का उपयोग करता है। इस विशेष मामले में, क्योंकि बीच में नामस्थान है, नाम मैंगलिंग अक्षम नहीं किया जा सकता है, इसलिए इसे किसी विशेष कॉलिंग सम्मेलन को लागू करने के लिए जोड़ा जा सकता था।

कोड वास्तव में गलत है कि घोषणा extern "C" को मजबूर नहीं करती है लेकिन परिभाषा करता है, जो गलत है। इस बात पर विचार करें कि यदि कंपाइलर ने दिखाए गए निर्देशों का पालन किया है, तो कॉलर सी ++ नामकरण और सम्मेलन को कॉल करेगा, जबकि समारोह सी संस्करण का उपयोग करेगा, यदि दोनों अलग-अलग परिणाम व्यवहार को अपरिभाषित करेंगे।

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