2008-10-26 17 views
55

कुछ कोड में मुझे विरासत मिली है, मुझे size_t का std नामस्थान योग्यता के साथ लगातार उपयोग दिखाई देता है। उदाहरण के लिए:क्या "std :: size_t" सी ++ में समझ में आता है?

std::size_t n = sizeof(long); 

यह निश्चित रूप से संकलित और चलाता है। लेकिन यह मेरे लिए बुरी प्रैक्टिस की तरह लगता है (शायद सी से ले जाया गया है?)।

क्या यह सच नहीं है कि size_t सी ++ में बनाया गया है और इसलिए वैश्विक नामस्थान में बनाया गया है? क्या एक हेडर फ़ाइल में C12+ में size_t का उपयोग करने की आवश्यकता है?

इस सवाल पूछने के लिए एक और तरीका है, है निम्नलिखित कार्यक्रम (के साथ कोई शामिल है) की उम्मीद की जा संकलन होगा सब सी ++ compilers पर?

size_t foo() 
{ 
    return sizeof(long); 
} 
+9

सी में नामस्थान नहीं हैं। – wnoise

+1

यह सी ++ में बनाया गया है, जब आप #शामिल करते हैं, और नामस्थान std में है। नीचे मेरा जवाब देखें। –

+2

यह 'इस सवाल से पूछने का एक और तरीका नहीं है' - यह एक अलग सवाल है: मुख्य रिटर्न int। – fizzer

उत्तर

126

वहाँ के विषय में इस

::size_t पश्चगामी संगतता हैडर stddef.h में परिभाषित किया गया है stackoverflow भीड़ के बीच भ्रम हो रहा है। यह उनकी शुरुआत के बाद से ANSI/ISO C और ISO C++ का हिस्सा रहा है। प्रत्येक सी ++ कार्यान्वयन को stddef.h (संगतता) और cstddef के साथ भेजना होता है जहां केवल बाद में std::size_t परिभाषित करता है और आवश्यक नहीं ::size_t। सी ++ मानक के अनुलग्नक डी देखें।

+12

बिल्कुल सबसे अच्छा जवाब यहाँ। यह एक विशेष संकलक के बजाय मानक पर आधारित है। यह टैंगेंट को भटकने के बिना मूल प्रश्न का उत्तर देता है। – Darryl

+2

'नामस्थान std' –

+0

@ डेरिल का उपयोग न करने का एक अन्य कारण: निष्पक्ष होने के लिए, सभी पुराने उत्तरों ने भी ऐसा किया। –

2

कभी-कभी अन्य पुस्तकालय अपने स्वयं के आकार_टी को परिभाषित करेंगे। उदाहरण के लिए बढ़ावा। std :: size_t निर्दिष्ट करता है कि आप निश्चित रूप से C++ मानक एक चाहते हैं।

size_t एक C++ मानक प्रकार है और इसे नामस्थान std के भीतर परिभाषित किया गया है।

+0

यह समझ में आता है। क्या आपको पता है कि ":: size_t" या "std :: size_t" (या शायद दोनों) भाषा spec का हिस्सा हैं? – jwfearn

4

size_t सी ++ में नहीं बनाया गया है। और यह डिफ़ॉल्ट रूप से परिभाषित नहीं है। यह एक जीसीसी के साथ संकलन नहीं करता है:

int main(int argc, char** argv) { 
size_t size; 
} 

जिसके अनुसार, size_t POSIX का हिस्सा है और अगर आप <cstdlib> की तरह केवल बुनियादी चीजें उपयोग करते हैं, आप की संभावना यह परिभाषित होने खत्म हो जाएगा।

आप तर्क दे सकते हैं कि std :: size_t size_t के बराबर सी ++ है। जैसा कि ब्रायन ने बताया, std :: को वैश्विक चर सेट करने से बचने के लिए नेमस्पेस के रूप में उपयोग किया जाता है जो सभी को फिट नहीं करता है। यह सिर्फ std :: स्ट्रिंग की तरह है, जिसे रूट नेमस्पेस में भी परिभाषित किया जा सकता है।

41

सी ++ मानक की धारा 17.4.1.2, पैरा 4, कहा गया है कि:

"सी ++ स्टैंडर्ड लाइब्रेरी में, हालांकि, घोषणाओं और परिभाषाओं (नाम जो सी में मैक्रो के रूप में परिभाषित कर रहे हैं को छोड़कर) के भीतर हैं नेमस्पेस std का नामस्थान स्कोप (3.3.5)। "

यह पैटर्न CNAME, cstddef सहित, जो size_t को परिभाषित करता है के शीर्ष लेख में पाया आइटम शामिल हैं।

तो std :: size_t वास्तव में सही है।

13

आप वैश्विक नामस्थान में size_t प्राप्त कर सकते हैं, उदाहरण के लिए, <stddef.h><cstddef> के बजाय। मुझे कोई स्पष्ट लाभ नहीं दिख रहा है, और सुविधा को हटा दिया गया है।

+0

डाउनवोट का कुछ स्पष्टीकरण विनम्र होगा। जवाब सही और विषय पर है। – fizzer

+0

मुझे नहीं पता कि आपको किसने वोट दिया था। आपका अवलोकन मूल प्रश्न के बिंदु पर बहुत अधिक है। –

+0

मैंने आपको वोट दिया, मुख्य रूप से क्योंकि ऐसा करने का एक गैर-बहिष्कृत तरीका है: घोषणाओं का उपयोग, यानी 'std :: size_t' का उपयोग करके, और आपने इसे बेहतर विकल्प के रूप में उल्लेख नहीं किया है। :-) – cic

1

जीएनयू संकलक हेडर की तरह

typedef long int __PTRDIFF_TYPE__; 
typedef unsigned long int __SIZE_TYPE__;

की तरह फिर stddef.h constains कुछ
typedef __PTRDIFF_TYPE__ ptrdiff_t; 
typedef __SIZE_TYPE__ size_t;

और अंत में cstddef फ़ाइल की तरह

 
#include <stddef.h> 

namespace std { 

    using ::ptrdiff_t; 
    using ::size_t; 

} 

कुछ मुझे लगता है कि कुछ शामिल इसे स्पष्ट करना चाहिए। जब तक आप <cstddef> शामिल करते हैं तो आप या तो size_t या std :: size_t का उपयोग कर सकते हैं क्योंकि size_t को std namespace के बाहर टाइप किया गया था और फिर उसे शामिल किया गया था। प्रभावी ढंग से आप

typedef long int ptrdiff_t; 
typedef unsigned long int size_t; 

namespace std { 

    using ::ptrdiff_t; 
    using ::size_t; 

} 
+0

तो जीएनयू इसे इस तरह परिभाषित करता है, करता है इसका मतलब है कि सभी कंपाइलर्स करते हैं? क्या मानक कहता है कि ऐसा होना चाहिए? – anthropomorphic

2

है मुझे लगता है कि स्पष्टीकरण पर्याप्त स्पष्ट हैं। std::size_t सी ++ और ::size_t में अच्छी समझ में आता है (कम से कम) सी

हालांकि एक प्रश्न बना रहता है। अर्थात् यह मानना ​​सुरक्षित है कि ::size_t और std::size_t संगत हैं?

शुद्ध प्रकार के परिप्रेक्ष्य से वे जरूरी नहीं हैं जब तक कि यह कहीं परिभाषित न हो कि वे समान होना चाहिए।

मुझे लगता है कि कई कुछ प्रयोग कर रहे हैं एक ला:

---- 
// a.hpp 
#include <string> 

void Foo(const std::string & name, size_t value); 

----- 
// a.cpp 
#include "a.hpp" 

using namespace std; 

void Foo(const string & name, size_t value) 
{ 
    ... 
} 

तो शीर्षक में आप defintely ::size_t का उपयोग करते समय स्रोत फ़ाइल में आप std::size_t का उपयोग करेंगे। तो वे संगत होना चाहिए, है ना? अन्यथा आपको एक कंपाइलर त्रुटि मिल जाएगी।

/माइकल एस

+2

:: size_t सी में समझ में नहीं आता है, जिसमें कोई नामस्थान नहीं है। –

4
std::size_t n = sizeof(long); 

असल में, आप नहीं पूछा है कि क्या विशेष रूप से ऊपर पूर्णांक एक बुरा व्यवहार हो रहा है। Size_t का उपयोग, std namespace के साथ योग्यता, ...

सी ++ मानक कहता है (18.1), size_t मानक शीर्षलेख में परिभाषित एक प्रकार है। मैं सी भाषा से संभावित विरासत के बारे में किसी भी विचार और छाप छोड़ने का सुझाव दूंगा। सी ++ एक अलग और अलग भाषा है और इसे इस तरह मानना ​​बेहतर है। इसकी अपनी मानक लाइब्रेरी है और सी ++ मानक लाइब्रेरी के सभी तत्वों को नेमस्पेस std के भीतर परिभाषित किया गया है। हालांकि, सी ++ कार्यक्रम में सी मानक पुस्तकालय के तत्वों का उपयोग करना संभव है।

मैं एक गंदे हैक के रूप में शामिल होने पर विचार करता हूं। सी ++ मानक बताता है कि हेडर की सामग्री सी मानक लाइब्रेरी से संबंधित शीर्षकों पर आधारित है, लेकिन मामलों की संख्या में, परिवर्तन लागू किए गए हैं। दूसरे शब्दों में, यह सी ++ हेडर में सी हेडर की सीधी प्रति & पेस्ट नहीं है।

size_t सी ++ में अंतर्निहित प्रकार नहीं है। यह निर्दिष्ट करने के लिए परिभाषित एक प्रकार है कि किस प्रकार का अभिन्न प्रकार आकार() ऑपरेटर के रिटर्न प्रकार के रूप में उपयोग किया जाता है, क्योंकि आकार का एक वास्तविक रिटर्न प्रकार कार्यान्वयन परिभाषित किया जाता है, इसलिए सी ++ मानक आकार_टी को परिभाषित करके एकीकृत करता है।

निम्नलिखित कार्यक्रम सभी सी ++ compilers पर संकलित करने के लिए उम्मीद की जा (कोई साथ शामिल है) हैं?

size_t foo() 
{ 
    return sizeof(long); 
} 

सी ++ मानक का कहना है (1.4):

नाम पुस्तकालय में परिभाषित नाम स्थान गुंजाइश (7.3) है। एक सी ++ अनुवाद इकाई (2.1) उपयुक्त मानक लाइब्रेरी हेडर (16.2) सहित इन नामों तक पहुंच प्राप्त करती है।

आकार_टी एक नाम है जो std namespace के भीतर परिभाषित किया गया है, इसलिए इस नाम का उपयोग करने वाले प्रत्येक प्रोग्राम में इस मामले में संबंधित शीर्षलेख शामिल होना चाहिए।

इसके बाद, 3.7.3 अध्याय का कहना है:

हालांकि, एसटीडी, एसटीडी :: bad_alloc, और std :: size_t की चर्चा करते हुए बीमार बनाई है जब तक कि नाम उचित हेडर सहित द्वारा घोषित किया गया है।

यह देखते हुए कि, size_t का उपयोग करने वाला प्रोग्राम लेकिन हेडर समेत प्रोग्राम खराब नहीं है।

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