2012-02-29 22 views
6

क्यों नहीं extern "C" एक फ़ंक्शन के लिए निर्दिष्ट किया जाना चाहिए जिसे सी फ़ंक्शन के रूप में परिभाषित करने की आवश्यकता है? फ़ाइल को सी स्रोत के रूप में संकलित करते समय संकलक पर इसका क्या प्रभाव होगा?क्या हम #ifdef __cplusplus के बिना सी फ़ाइल में बाहरी "सी" का उपयोग कर सकते हैं?

यदि सी कंपाइलर पर कोई प्रभाव नहीं पड़ता है, तो क्या हम #ifdef __cplusplus को हटाकर नीचे एक शीर्षलेख फ़ाइल में फ़ंक्शन को परिभाषित नहीं कर सकते हैं?

extern "C" { 
    int MyFunc(); 
} 

An answer to another question का कहना है कि #ifdef जरूरत है, लेकिन मुझे समझ नहीं आता क्यों:

के बारे में # 2: __cplusplus किसी भी संकलन इकाई है कि सी ++ संकलक के माध्यम से चलाया जा रहा के लिए परिभाषित किया जाएगा। आम तौर पर, इसका मतलब है .cpp फ़ाइलें और उस फ़ाइल को उस .cpp फ़ाइल द्वारा शामिल किया जा रहा है। अलग-अलग संकलन इकाइयों में शामिल होने पर, वही .h (या .hh या .hpp या what-have-you) को अलग-अलग समय में सी या सी ++ के रूप में व्याख्या किया जा सकता है। यदि आप सी प्रतीक नामों को संदर्भित करने के लिए .h फ़ाइल में प्रोटोटाइप चाहते हैं, तो उनके पास C12+ के रूप में व्याख्या किए जाने पर extern "C" होना चाहिए, और उनके पास extern "C" नहीं होना चाहिए जब सी के रूप में व्याख्या की जा रही हो - इसलिए #ifdef __cplusplus जांच।

उत्तर

13

निर्माण extern "C" एक सी ++ निर्माण है और सी संकलक द्वारा मान्यता प्राप्त नहीं है। आमतौर पर, यह एक वाक्यविन्यास त्रुटि संदेश जारी करेगा।

एक आम चाल एक मैक्रो को परिभाषित करना है, उदाहरण के लिए EXTERN_C, जो सी या सी ++ का उपयोग करके संकलित करते हैं, इस पर निर्भर करता है कि यह अलग-अलग चीज़ों में विस्तारित होगा।

एक आम हेडर फाइल में:

#ifdef __cplusplus 
#define EXTERN_C extern "C" { 
#define EXTERN_C_END } 
#else 
#define EXTERN_C 
#define EXTERN_C_END 
#endif 

अन्य फ़ाइलों में:

EXTERN_C 
int MyFunc(void); 
EXTERN_C_END 
+1

धन्यवाद। मुझे नहीं पता था कि यह एक सी ++ निर्माण था। – Alexander

2

आप सी के रूप में एक स्रोत फ़ाइल संकलन है, यह नहीं पहचान लेंगे extern "C", और होगा उदाहरण के लिए आमतौर पर एक संकलन त्रुटि में परिणाम।

आप सी ++ के रूप में एक स्रोत फ़ाइल संकलन है, यह extern "C" पहचान नहीं करेगा और सही नाम लिंक किया जाएगा।

इसलिए, आप केवल C++ के रूप में संकलित फ़ाइलों के लिए सी प्रतीक नाम निर्दिष्ट करने के लिए विश्वसनीय रूप से इसका उपयोग कर सकते हैं।

यदि आप सी और सी ++ के रूप में स्रोतों को संकलित करते हैं, या आपके इंटरफेस सी और सी ++ क्लाइंट के लिए हैं, तो आपको लिंक करने के दौरान अपने ग्राहकों को सही प्रतीक प्राप्त करने के लिए इसे एक या दूसरे तरीके से निर्दिष्ट करने की आवश्यकता होगी (और इसी तरह)।

संबंधित: को extern "C++" लिखने की अनुमति है - सी ++ अनुवादों के लिए।

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