C ++ में C हेडर का उपयोग करते समय, क्या हमें std :: या ग्लोबल नेमस्पेस से कार्यों का उपयोग करना चाहिए?


113

C कुछ है, बिल्कुल नहीं, C ++ का सबसेट। इसलिए हम C ++ के ज्यादातर C फंक्शन्स / हेडर्स को नाम में थोड़ा-थोड़ा बदलकर ( stdio.hto cstdio, stdlib.hto cstdlib) इस्तेमाल कर सकते हैं।

मेरा प्रश्न वास्तव में एक प्रकार का शब्दार्थ है। सी ++ कोड में (जीसीसी संकलक के नवीनतम संस्करण का उपयोग कर), मैं कॉल कर सकते हैं printf("Hello world!");और std::printf("Hello world!");और यह बिल्कुल वैसा ही काम करता है। और जिस संदर्भ में मैं इसका उपयोग कर रहा हूं वह भी इस रूप में दिखाई देता है std::printf("Hello world!");

मेरा सवाल है, क्या इसे std::printf();C ++ में इस्तेमाल करना पसंद है ? क्या कोई अंतर है?


17
इस घटना में कि एक दिन वे Cवैश्विक प्रतीकों में पुस्तकालय प्रतीकों के डंपिंग को अनिवार्य करते हैं, मैं अवैध रूप से std::योग्य संस्करणों का उपयोग करना पसंद करता हूं । (प्लस मैं चाहता हूं कि उन्होंने इसे अवैध बना दिया)।
गलिक

3
@ जालिक: सहमत। कि C ++ कंपाइलर का उपयोग करके C के मुद्दों के बारे में बहुत सारे मूर्खतापूर्ण प्रश्न सुरक्षित होंगे।
इस साइट के लिए बहुत ईमानदार

7
कोई "थोड़ा सा गर्भवती" नहीं है। या तो C एक सबसेट है, या यह नहीं है। तथ्य है, यह नहीं है । यही कारण है कि सी हेडर को सी ++ में काम करने के लिए संशोधित करना होगा।
इस साइट के लिए बहुत ईमानदार

2
बेशुमार कई तत्वों के सेट के बारे में बात करते समय "लगभग सभी" एक बहुत ही बेकार उपाय है। उसी तर्क से आप शायद C और Java से संबंधित हो सकते हैं।
डैनियल जर्स

9
@sasauke नहीं, यह एक सबसेट नहीं है। C और C ++ निश्चित रूप से एक सबसेट साझा करते हैं, लेकिन C स्वयं C ++ का सबसेट नहीं है।
पैरामैग्नेटिक क्रोइसैंट

जवाबों:


106

C ++ 11 मानक (जोर मेरा) से:

D.5 C मानक लाइब्रेरी हेडर [depr.c.headers]

  1. सी मानक पुस्तकालय के साथ संगतता के लिए ...
  2. प्रत्येक C हेडर, जिनमें से प्रत्येक का नाम name.h है , व्यवहार करता है जैसे कि प्रत्येक नाम के अनुरूप सीनाम हैडर द्वारा मानक लाइब्रेरी नेमस्पेस में रखा गया प्रत्येक नाम ग्लोबल नेमस्पेस दायरे में रखा गया है । यह अनिर्दिष्ट है कि इन नामों को पहले घोषित किया गया है या नाम स्थान std के नाम स्थान गुंजाइश (3.3.6) में परिभाषित किया गया है और फिर स्पष्ट उपयोग-घोषणाओं (7.3.3) द्वारा वैश्विक नाम स्थान गुंजाइश में इंजेक्ट किया जाता है।
  3. उदाहरण: हैडर <cstdlib> विश्वासपूर्वक अपनी घोषणाओं और परिभाषाओं प्रदान करता है नाम स्थान के अंदर std । यह वैश्विक नामस्थान के भीतर ये नाम भी प्रदान कर सकता है। हेडर <stdlib.h> आश्वस्त रूप से वैश्विक नेमस्पेस के भीतर समान घोषणाएं और परिभाषाएं प्रदान करता है , जितना कि सी स्टैंडर्ड में। यह इन नामों को नामस्थान के भीतर भी प्रदान कर सकता है std

«Name.h» हेडर का उपयोग करके पदावनत किया जाता है, उन्हें भविष्य के संशोधनों से हटाने के लिए उम्मीदवारों के रूप में पहचाना जाता है।

इसलिए, मैं «cname» हेडर को शामिल करने और stdनाम स्थान से घोषणाओं और परिभाषाओं का उपयोग करने का सुझाव दूंगा ।

यदि आपको कुछ कारणों से «name.h» हेडर का उपयोग करना है (यह पदावनत है, तो ऊपर देखें), मैं वैश्विक नाम स्थान से घोषणाओं और परिभाषाओं का उपयोग करने का सुझाव दूंगा।

दूसरे शब्दों में: पसंद करते हैं

#include <cstdio>

int main() {
    std::printf("Hello world\n");
}

ऊपर

#include <stdio.h>

int main() {
    printf("Hello world\n");
}

1
N3242 कोई C ++ मानक नहीं है। N3337 C ++ 11 से सबसे कम अंतर के साथ मसौदा।
MM

3
यह भी देखें कि जोनाथन वेक्ली की व्हाईट <cstdlib> रेड हैट ब्लॉग्स की तुलना में अधिक जटिल है । वह C ++ मानक पुस्तकालय कार्यान्वयनकर्ता के दृष्टिकोण से कई समस्याओं का विवरण देता है। वह C ++ 98 पर वापस जाने का इतिहास भी प्रदान करता है।
jww

@sergej - क्या आप इस विषय पर C ++ 03 उपचार जानना चाहेंगे? या यह हिट है या मिस क्या होगा?
jww

5
<name.h> पदावनत किया जा सकता है, कोई मौका नहीं है कि वे जल्द ही किसी भी समय हटा दिए जाएंगे। वास्तव में, बिल्कुल विपरीत है। हटाए गए लेबल को हटाने का प्रस्ताव है, खुले-std.org/JTC1/SC22/WG21/docs/papers/2017/p0619r0.html#3.5 देखें । "अंत में, यह स्पष्ट लगता है कि सी हेडर अनिवार्य रूप से हमेशा के लिए सी और पॉसिक्स के साथ एक महत्वपूर्ण संगतता परत के रूप में बनाए रखा जाएगा। यह हेडर को छोटा करने के लायक हो सकता है, [..]"
सॉज़र्ड

82

<cmeow>हमेशा प्रदान करता है ::std::purrऔर प्रदान कर सकता है या नहीं भी कर सकता है ::purr

<meow.h>हमेशा प्रदान करता है ::purrऔर प्रदान कर सकता है या नहीं भी कर सकता है ::std::purr

आपके द्वारा शामिल किए गए शीर्ष लेख द्वारा प्रदान की जाने वाली गारंटी का उपयोग करें।


7
गरीब भेस में एसटीएल?
nwp

@ एनडब्ल्यूपी नप। (15 वर्ण)
टीसी

@TC दुर्भाग्य से, जैसा कि मैंने अपने संकलक पर कोशिश की, न तो <cmeow>और न ही <meow.h>प्रदान करता है और न ::std::purrही ::purrबल्कि पूर्व-प्रोसेसर त्रुटि। केवल <cstdio>और / या <stdio.h>प्रदान करता है ::std::printfऔर / या ::printf। : पी
एलएफ

4
@ एलएफ आपको strcatउत्पादन करने की आवश्यकता हो सकती है ::purr
लंडिन

8

नहीं, आप किसी भी तरह से ठीक हैं।

मूल आशय था कि <___.h>हेडर सी संस्करणों जो ग्लोबल नेम स्पेस में सब कुछ डाल दिया होगा, और <c___>हेडर सी ++ होगा - वर्गीकृत संस्करणों है, जो जगह में सब कुछ stdनाम स्थान।

व्यवहार में, हालांकि, C ++ संस्करणों ने भी वैश्विक नेमस्पेस में सब कुछ डाल दिया। और कोई स्पष्ट सहमति नहीं है कि std::संस्करणों का उपयोग करना "सही काम करना है"।

इसलिए मूल रूप से, आप जो भी पसंद करते हैं उसका उपयोग करें। वैश्विक नाम स्थान में C मानक लाइब्रेरी फ़ंक्शंस का उपयोग करने के लिए संभवतः सबसे आम है ( printfइसके बजाय std::printf), लेकिन एक "बेहतर" पर विचार करने का कोई कारण नहीं है।


2
"और कोई स्पष्ट सहमति नहीं है कि std :: संस्करणों का उपयोग करना" सही काम है "।" उह, हाँ बिलकुल सर्वसम्मति है कि यह सही काम है।
माइल्स राउत

4
एक उद्देश्य कैसे निर्धारित करता है कि क्या आम सहमति बन गई है या नहीं?
जेरेमी फ्रेज़र

9
@JeremyFriesner आप इसके बारे में एसओ पर पोस्ट करते हैं और देखें कि क्या आपको असहमतिपूर्ण टिप्पणियां मिलती हैं। :)
जालपा

1
@ जेरेमीफ़्रीज़र: मानक सी ++ हेडर संस्करणों की गारंटी नहीं देता है जिससे पहचानकर्ताओं को वैश्विक नामस्थान में रखा जा सके। मानक सी हेडर संस्करणों को भी चित्रित करता है। यह मुझे बहुत अच्छा लग रहा है। ;-)
DevSolar

2
@DevSolar एक शब्दकोश में "आम सहमति" शब्द को देखता है। यह मानक क्या कहता है, इसके बारे में नहीं है, लेकिन सी ++ प्रोग्रामर क्या कहते हैं - और विशेष रूप से, वे क्या करते हैं । एक कारण यह है कि शाब्दिक रूप से प्रत्येक मानक पुस्तकालय कार्यान्वयन सी हेडर प्रदान करता है, और सी ++ हेडर ने वैश्विक नामस्थान में भी सब कुछ डाल दिया है। :)
जुल्फ

3

अंतर केवल इतना है कि स्कोप रिज़ॉल्यूशन std::printf()को जोड़कर std::आप भविष्य में उसी नाम के साथ एक फ़ंक्शन लिखने वाले किसी व्यक्ति से खुद को सुरक्षित करेंगे, जिससे नाम स्थान संघर्ष हो सकता है। दोनों usages बिल्कुल एक ही OS API कॉल्स को लीड करेंगे (आप इसे लिनक्स के तहत रन करके चेक कर सकते हैं strace your_program)।

मुझे यह बहुत कम संभावना है कि कोई इस तरह के एक फ़ंक्शन का नाम देगा, जैसा कि printf()वहां सबसे अधिक उपयोग किए जाने वाले कार्यों में से एक है। इसके अलावा, सी ++ में, iostreamप्रिंट की cstdioतरह कार्यों के लिए कॉल पर प्रीफ़र्ड किया जाता है।


1
इसके विपरीत, मुझे यह काफी संभावना लगता है: printfमजबूत टाइपिंग की कमी के कारण सी ++ में संभवतः टूट गया है, इसे बेहतर संस्करण के साथ बदलना काफी स्वाभाविक है।
कोनराड रुडोल्फ

1
@KonradRudolph यदि आप चाहें तो इसे पा सकते हैं, लेकिन आप गलत होंगे; इसका मतलब मजबूत टाइपिंग नहीं है, और कई समस्याएं हैं जिन्हें आसानी से आवश्यक मजबूत टाइपिंग से हल नहीं किया जा सकता है। यही कारण है कि कई तुलनीय C ++ समाधान प्रिंटफ की तुलना में बहुत धीमी हैं। यदि आप इसे "बेहतर" संस्करण के साथ बदलना चाहते हैं, तो आप भाषा और प्रोग्रामर के बीच अनुबंध को तोड़ रहे हैं, और शुरू करने के लिए पाप की स्थिति में हैं।
ऐलिस

1
@ ऐलिस उम्म, मैं कोई अनुबंध नहीं तोड़ रहा हूं: इससे std::printfअलग है mynamespace::printf, और सी ++ मुझे स्पष्ट रूप से अपने स्वयं के कार्यों को परिभाषित करने की अनुमति देता है जिनके नाम उन कार्यों के अंदर से छाया करते हैं std। यह बस बहस नहीं है। printfढीले टाइपिंग के कारण कुशल होने वाले आपके दावों के लिए , यह भी गलत है। printfविशेष रूप से कुशल भी नहीं है, कई और अधिक कुशल कार्यान्वयन हैं जो दृढ़ता से टाइप किए गए हैं।
कोनराड रुडोल्फ

@KonradRudolph बिलकुल गलत; आप अनुबंध को तोड़ रहे हैं, जो मानक में लिखा गया है, बिना किसी क्वांटिफायर के प्रिंटफ सी निर्माण के लिए अलग से लागू होता है। ग्लोबल नेमस्पेस को अलियास करते हुए एक नेमस्पेस का आपका उपयोग एक अच्छा विचार नहीं है। यह बस बहस नहीं है
ऐलिस

5
@ क्या आप कृपया इस पर मानक का हवाला दे सकते हैं? मुझे ऐसी किसी भी क्रिया के बारे में जानकारी नहीं है।
कोनराड रुडोल्फ

3

C ++ 11 मानक से:

प्रत्येक C हेडर, जिनमें से प्रत्येक का नाम name.h है, व्यवहार करता है जैसे कि प्रत्येक नाम के अनुरूप सीनाम हैडर द्वारा मानक लाइब्रेरी नेमस्पेस में रखा गया प्रत्येक नाम ग्लोबल नेमस्पेस दायरे में रखा गया है। यह अनिर्दिष्ट है कि इन नामों को पहले घोषित किया गया है या नाम स्थान std के नाम स्थान गुंजाइश (3.3.6) में परिभाषित किया गया है और फिर स्पष्ट उपयोग-घोषणाओं (7.3.3) द्वारा वैश्विक नाम स्थान गुंजाइश में इंजेक्ट किया जाता है।

इसलिए, यदि आप उपयोग करते हैं, तो आप <cstdio>सुनिश्चित हो सकते हैं, कि printfयह namespace stdवैश्विक नाम स्थान में नहीं है और इसलिए नहीं होगा।
वैश्विक नामस्थान का उपयोग नामों का टकराव पैदा करता है। यह C ++ तरीका नहीं है।

इसलिए, मैं <cstdio>हेडर का उपयोग कर रहा हूं और आपको ऐसा करने की सलाह देता हूं।


4
हालांकि काश यह इस तरह से काम करता, यह सच नहीं है। यदि आप शामिल <cstdio>करते हैं तो आपको गारंटी दी जाती है कि std :: printf मौजूद होगा, लेकिन मानक से कोई गारंटी नहीं है यदि :: printf मौजूद होगा या नहीं भी होगा। वास्तव में, हर कंपाइलर के बारे में मैंने कभी सुना है: प्रिंटफ को आपके द्वारा शामिल किए जाने पर वैश्विक नामस्थान में इंजेक्ट किया जाता है <cstdio>
wjl

3

मेरे अपने अभ्यास से: std::उपसर्गों का उपयोग करें । अन्यथा एक दिन आपको फ्लोटिंग पॉइंट्स का उपयोग करने की स्थिति में बहुत दर्द abs होगा

गैर-योग्य कुछ प्लेटफार्मों पर absपरिभाषित फ़ंक्शन को संदर्भित करता है int। दूसरों पर यह अतिभारित है। हालांकि std::absहमेशा सभी प्रकार के लिए अतिभारित होता है।


2

printfबिना std::नाम का उपयोग किए केवल कुछ नाम संघर्ष उत्पन्न हो सकते हैं और इसे बहुत सारे c ++ देवों द्वारा एक बुरा अभ्यास माना जाता है। Google इस पर आपका मित्र है, लेकिन यहां कुछ लिंक दिए गए हैं, आशा है कि यह मदद करता है

क्यों "नेमस्पेस स्टड का उपयोग करना" बुरा व्यवहार माना जाता है? http://www.cplusplus.com/forum/beginner/61121/


4
using namespace stdएक बुरा अभ्यास है लेकिन क्वालीफायर के printfबिना उपयोग std::करना नहीं है।
वाक्यगुप्त

using namespace std;यहाँ मेरी समस्या नहीं है। मैं इसका इस्तेमाल कभी नहीं करता। printf();और std::printf();C ++ में काम करें, using namespace std;इसीलिए मैंने प्रश्न पोस्ट किया।
देईदेई

@REACHUS असहमत। दोनों परिदृश्यों में कोई अंतर नहीं है।
कोनराड रुडोल्फ

मैं इसका इस्तेमाल कभी नहीं करूँगा std::printfबस यह सादा अजीब लगता है।
trenki

@KonradRudolph मैंने यह नहीं कहा कि इसमें कोई अंतर है, मैंने सिर्फ अपनी राय व्यक्त की (अधिक तर्क के लिए मेरा जवाब देखें)।
वाक्यगुप्त

2

Stdio में

यह मानक C लाइब्रेरी हेडर @c stdio.h का C ++ संस्करण है, और इसकी सामग्री (अधिकतर) उस हेडर के समान हैं, लेकिन ये सभी नामस्थान @ c std में हैं (केवल नाम के लिए जिन्हें मैक्रोज़ के रूप में परिभाषित किया गया है) सी)।

इसलिए इससे कोई फर्क नहीं पड़ना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.