2011-11-10 24 views
9

क्या मुझे C12+ प्रोग्राम में मानक सी शीर्षलेखों को शामिल करने के लिए extern "C" {} ब्लॉक की आवश्यकता है। केवल मानक सी शीर्षकों पर विचार करें जिनके पास सी ++ में समकक्ष नहीं हैं।क्या मुझे मानक सी शीर्षलेखों को शामिल करने के लिए बाहरी "सी" ब्लॉक की आवश्यकता है?

उदाहरण के लिए:

extern "C" { 
#include <fcntl.h> 
#include <unistd.h> 
} 
+0

बस यह प्रश्न आपके जैसा ही पाया गया है: [हमें सी ++ में बाहरी "सी" {#in33e } क्यों चाहिए?] (Http://stackoverflow.com/questions/67894/why-do-we-need -अंटर-सी-इन-फू-एच-इन-सी) – AusCBloke

उत्तर

7

सी ++ में <fcntl.h> और <unistd.h> का व्यवहार मानक द्वारा निर्दिष्ट नहीं है (क्योंकि वे C89 मानक का भी हिस्सा नहीं हैं)। उस ने कहा, मैंने कभी ऐसा मंच नहीं देखा है जहां वे (ए) मौजूद हैं और (बी) वास्तव में extern "C" ब्लॉक में लपेटने की आवश्यकता है।

<stdio.h>, <math.h> का व्यवहार, और अन्य मानक सी शीर्षलेख C++ 03 मानक के अनुभाग डी.5 द्वारा निर्दिष्ट किया गया है। उन्हें extern "C" रैपर ब्लॉक की आवश्यकता नहीं है, और वे अपने प्रतीकों को वैश्विक नामस्थान में डंप करते हैं। हालांकि, एनेक्स डी में सबकुछ "बहिष्कृत" है।

विहित सी ++ उन हेडर के रूप में, <cstdio> है <cmath>, आदि, और वे खंड 17.4.1.2 द्वारा निर्दिष्ट (3) सी ++ मानक, जो कहते हैं की:

<cassert> <ciso646> <csetjmp> <cstdio> <ctime> <cctype> <climits> 
<csignal> <cstdlib> <cwchar> <cerrno> <clocale> <cstdarg> <cstring> 
<cwctype> 

के रूप में छोड़कर क्लॉज 18 से 27 में उल्लिखित, प्रत्येक शीर्षलेख की सामग्री cname इसी शीर्षलेख नाम.h के समान होगी, आईएसओ/आईईसी 98 99: 1 99 0 प्रोग्रामिंग भाषा सी (क्लॉज 7), या आईएसओ/आईईसी: 1 99 0 प्रोग्रामिंग भाषा-सी संशोधन 1: सी ईमानदारी, (खंड 7), एपी के रूप में मालिकाना, जैसे कि शामिल करके। सी ++ मानक लाइब्रेरी में, हालांकि, घोषणाओं और परिभाषाओं ( नामों के अलावा सी में मैक्रोज़ के रूप में परिभाषित नामों को छोड़कर) नामस्थान std के नामस्थान स्कोप (3.3.5) के भीतर हैं।

तो मानक, गैर पदावनत, विहित तरीके से उपयोग करने (जैसे) सी ++ में printf#include <cstdio> है और फिर std::printf आह्वान।

1

नहीं, आप सी ++ आवरण हेडर (उदाहरण के लिए <cstdio>) की तरह उपयोग करना चाहिए। वे आपके लिए यह सब ख्याल रखते हैं।

यदि यह एक शीर्षलेख है जिसमें उनके पास नहीं है, तो हाँ, आप उन्हें extern "C" {} में लपेटना चाहेंगे।

ईटीए: यह ध्यान देने योग्य है कि कई कार्यान्वयन में नीचे की तरह .h फ़ाइल के अंदर रैपर शामिल होगा, ताकि आप इसे स्वयं नहीं कर सकें।

#ifdef __cplusplus 
extern "C" { 
#endif 

#ifdef __cplusplus 
} 
#endif 
+0

यह ध्यान देने योग्य है कि '' आदि शीर्षलेख तकनीकी रूप से 'डीडीडी नेमस्पेस' में अपनी परिभाषा डालते हैं। (कई कार्यान्वयन उन्हें शीर्ष-स्तरीय नेमस्पेस में भी डालते हैं, लेकिन यह मानक नहीं कहता है।) – Nemo

-1

यह इतना है कि यह जब C++ संकलन सी कोड उम्मीद कर सकते हैं यह बताने के लिए संकलक पता एक अच्छा विचार है। आप यह भी पा सकते हैं कि शीर्षलेख फ़ाइलों में स्वयं के रूप में extern "C" { शामिल हैं।

अपने सिस्टम पर

उदाहरण के लिए, curses.h शामिल हैं:

#ifdef __cplusplus 
extern "C" { 
... 
+0

* "संकलक को यह बताएं कि सी ++ के रूप में संकलित होने पर सी कोड की उम्मीद हो सकती है" * - यह 'बाहरी' नहीं है सी "' करता है। यह कोड की व्याख्या नहीं बदलता है। यह कोड पर भी लागू नहीं होता है। यह एक भाषा संबंध निर्देश है जो संकलक को सी के लिए उम्मीदवारों के साथ संगत प्रतीकों को उत्पन्न करने के लिए निर्देश देता है। यह सी ++ कोड को सी से कॉल करने योग्य बनाता है, लेकिन कोड जनरेशन नहीं बदलता है। – IInspectable

+0

@Inpectpectable _ "संकलक को उन लोगों के साथ संगत प्रतीकों को उत्पन्न करने के लिए निर्देश देता है जो लिंकर अपेक्षा करते हैं" _ का मतलब है कि यह कोड पर लागू होता है, या कम से कम कोड का कॉलिंग सम्मेलन? यह निश्चित रूप से संकलक (साथ ही लिंकर) को कुछ बता रहा है। – Tanz87

+0

@ Tanz87: यह कोड पीढ़ी को थोड़ा सा नहीं बदलता है। जेनरेट ऑब्जेक्ट कोड 'बाहरी' सी के बिना या उसके समान है। निर्देश केवल नामकरण प्रतीक पर लागू होता है। यह सम्मेलन बुलावा पर कोई असर नहीं है। – IInspectable

1

हाँ, आप कर सकते हैं। हालांकि, कई सिस्टम (विशेष रूप से लिनक्स) पहले से ही extern "C" ब्रैकेटिंग जोड़ रहे हैं जैसे आप करते हैं। देखें (लिनक्स पर) /usr/include/unistd.h/usr/include/features.h और मैक्रो __BEGIN_DECLS/usr/include/sys/cdefs.h में परिभाषित और कई लिनक्स सिस्टम में उपयोग की गई फाइलें शामिल हैं।

तो लिनक्स पर, आप आमतौर पर अपने extern "C" से बच सकते हैं लेकिन इससे नुकसान नहीं होता है (और, IMHO, उस मामले में पठनीयता में सुधार)।

11

सिस्टम सी हेडर आमतौर पर extern "C" ब्लॉक शामिल हैं, #ifdef __cplusplus द्वारा संरक्षित। सी ++ के रूप में संकलित होने पर फ़ंक्शन स्वचालित रूप से extern "C" के रूप में घोषित किए जाते हैं और आपको इसे मैन्युअल रूप से करने की आवश्यकता नहीं होती है। __END_DECLS साथ

अपने सिस्टम unistd.h पर

उदाहरण के लिए और __BEGIN_DECLS साथ fcntl.h आरंभ और अंत है, जो मैक्रो sys/cdefs.h में परिभाषित कर रहे हैं:

/* C++ needs to know that types and declarations are C, not C++. */ 
#ifdef __cplusplus 
# define __BEGIN_DECLS extern "C" {            
# define __END_DECLS } 
#else 
# define __BEGIN_DECLS 
# define __END_DECLS 
#endif 
2

मेरी राय में यह हेडर फाइल के निर्यात का कर्तव्य निर्वासन उपयोग करने के लिए 'सी है "उचित रूप से।

0

मैंने जीएनयू कंपाइलर के लिए सिर्फ stdlib.h की जांच की है और घोषणाएं घोषणा के रूप में बाहरी "सी" का उपयोग नहीं करती हैं।

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

if defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES 
define __BEGIN_NAMESPACE_STD namespace std { 
तो वर्ष हेडर एसटीडी प्रदान की _GLIBCPP_USE_NAMESPACES पर घोषणाओं स्थापित करेंगे सहित

परिभाषित किया गया है?

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