C++
कार्यान्वयन-परिभाषित व्यवहार
खोज…
चार को अहस्ताक्षरित या हस्ताक्षरित किया जा सकता है
मानक निर्दिष्ट नहीं करता है कि क्या char पर हस्ताक्षर किए या अहस्ताक्षरित होने चाहिए। विभिन्न कंपाइलर इसे अलग तरीके से लागू करते हैं, या कमांड लाइन स्विच का उपयोग करके इसे बदलने की अनुमति दे सकते हैं।
अभिन्न प्रकार का आकार
निम्नलिखित प्रकारों को अभिन्न प्रकारों के रूप में परिभाषित किया गया है:
-
char - पूर्णांक प्रकार पर हस्ताक्षर किए
- निरुपित पूर्णांक प्रकार
-
char16_tऔरchar32_t -
bool -
wchar_t
sizeof(char) / sizeof(signed char) / sizeof(unsigned char) के अपवाद के साथ, जो between 3.9.1.1 [बेसिक.फ़ंडमेंटल / 1] और .3 5.3.3.1 के बीच विभाजित है [expr.sizeofof, और sizeof(bool) , जो पूरी तरह से कार्यान्वयन-परिभाषित है और इसका कोई न्यूनतम आकार नहीं है, इन प्रकारों की न्यूनतम आकार की आवश्यकताओं को मानक के खंड f 3.9.1 [बुनियादी.फंडामेंटल] में दिया गया है, और नीचे विस्तृत होगा।
char आकार
सी ++ मानक के सभी संस्करणों, § 5.3.3.1 में, निर्दिष्ट करें कि sizeof पैदावार 1 के लिए unsigned char , signed char , और char (यह परिभाषित है कि क्या कार्यान्वयन है char प्रकार है signed या unsigned )।
UTF-8 कोड इकाइयों के भंडारण के लिए उपयुक्त होने के लिए, char अलग-अलग मूल्यों को दर्शाने के लिए char काफी बड़ा है।
हस्ताक्षरित और अहस्ताक्षरित पूर्णांक प्रकारों का आकार
मानक निर्दिष्ट करता है, .1 3.9.1.2 में, कि मानक हस्ताक्षरित पूर्णांक प्रकारों की सूची में, signed char , short int , int , long int , और long long int मिलकर प्रत्येक प्रकार कम से कम उतना भंडारण प्रदान करेगा जितना कि पूर्ववर्ती। यह सूची में है। इसके अलावा, जैसा कि .1 3.9.1.3 में निर्दिष्ट किया गया है, इन प्रकारों में से प्रत्येक के पास एक समान मानक अहस्ताक्षरित पूर्णांक प्रकार , unsigned char , unsigned short int , unsigned int , unsigned long int , और unsigned long long int , जिसका आकार और संरेखण है इसके अनुरूप हस्ताक्षरित प्रकार। इसके अतिरिक्त, जैसा कि .1 3.9.1.1 में निर्दिष्ट किया गया है, चार्ट पर signed char और unsigned char रूप में char का आकार समान है और संरेखण आवश्यकताएं हैं।
C ++ 11 से पहले, long long और unsigned long long आधिकारिक तौर पर C ++ मानक का हिस्सा नहीं थे। हालाँकि, C99 में C के लिए उनके परिचय के बाद, कई संकलक एक विस्तारित हस्ताक्षरित पूर्णांक प्रकार के रूप में long long समर्थन करते थे, और unsigned long long तक बिना विस्तारित पूर्णांक पूर्णांक के रूप में unsigned long long तक बिना किसी प्रकार के सी नियमों के साथ समर्थन करते थे।
मानक इस प्रकार गारंटी देता है कि:
1 == sizeof(char) == sizeof(signed char) == sizeof(unsigned char)
<= sizeof(short) == sizeof(unsigned short)
<= sizeof(int) == sizeof(unsigned int)
<= sizeof(long) == sizeof(unsigned long)
<= sizeof(long long) == sizeof(unsigned long long)
प्रत्येक प्रकार के लिए विशिष्ट न्यूनतम आकार मानक द्वारा नहीं दिए गए हैं। इसके बजाय, प्रत्येक प्रकार में मूल्यों की न्यूनतम सीमा होती है, जो इसका समर्थन कर सकते हैं, जो as 3.9.1.3 में निर्दिष्ट है, C मानक से विरासत में, a5.2.4.2.1 में। प्रत्येक प्रकार का न्यूनतम आकार आवश्यक रूप से बिट्स की न्यूनतम संख्या निर्धारित करके, इस सीमा से मोटे तौर पर अनुमान लगाया जा सकता है; ध्यान दें कि किसी भी प्लेटफ़ॉर्म के लिए, किसी भी प्रकार की वास्तविक समर्थित सीमा न्यूनतम से बड़ी हो सकती है। ध्यान दें कि हस्ताक्षरित प्रकारों के लिए, सीमाएं किसी के पूरक के अनुरूप हैं, न कि आमतौर पर उपयोग किए गए दो के पूरक; यह मानक के अनुपालन के लिए प्लेटफार्मों की एक विस्तृत श्रृंखला को अनुमति देने के लिए है।
| प्रकार | न्यूनतम सीमा | न्यूनतम बिट्स की आवश्यकता है |
|---|---|---|
signed char | -127 से 127 (- (2 7 - 1) से (2 7 - 1)) | 8 |
unsigned char | 0 से 255 (0 से 2 8 - 1) | 8 |
signed short | -32,767 से 32,767 (- (2 15 - 1) से (2 15 - 1)) | 16 |
unsigned short | 0 से 65,535 (0 से 2 16 - 1) | 16 |
signed int | -32,767 से 32,767 (- (2 15 - 1) से (2 15 - 1)) | 16 |
unsigned int | 0 से 65,535 (0 से 2 16 - 1) | 16 |
signed long | -2,147,483,647 से 2,147,483,647 (- (2 31 - 1) से (2 31 - 1)) | 32 |
unsigned long | 0 से 4,294,967,295 (0 से 2 32 - 1) | 32 |
| प्रकार | न्यूनतम सीमा | न्यूनतम बिट्स की आवश्यकता है |
|---|---|---|
signed long long | -9,223,372,036,854,775,807 से 9,223,372,036,854,775,807 (- (2 63 - 1) से (2 63 - 1)) | 64 |
unsigned long long | 0 से 18,446,744,073,709,551,615 (0 से 2 64 - 1) | 64 |
जैसा कि प्रत्येक प्रकार को इसकी न्यूनतम आकार की आवश्यकता से अधिक होने की अनुमति है, प्रकार कार्यान्वयन के बीच आकार में भिन्न हो सकते हैं। इस का सबसे उल्लेखनीय उदाहरण 64-बिट डेटा मॉडल LP64 और LLP64, जहां LLP64 सिस्टम (जैसे 64-बिट Windows) 32-बिट के साथ है ints और long है, और LP64 सिस्टम (जैसे कि 64-बिट लिनक्स के रूप में) है 32-बिट int एस और 64-बिट long एस। इसके कारण, पूर्णांक प्रकारों को सभी प्लेटफार्मों पर एक निश्चित चौड़ाई के लिए नहीं माना जा सकता है।
यदि निश्चित चौड़ाई वाले पूर्णांक प्रकारों की आवश्यकता है, तो <cstdint> शीर्ष लेख से प्रकारों का उपयोग करें, लेकिन ध्यान दें कि मानक इसे सटीक-चौड़ाई प्रकारों int8_t , int16_t , int32_t , int64_t , intptr_t , uint8_t , uint16_t , uint32_t का समर्थन करने के लिए वैकल्पिक बनाता है। , uint64_t और uintptr_t
char16_t और char32_t का आकार
char16_t और char32_t का आकार कार्यान्वयन-परिभाषित है, जैसा कि char 5.3.3.1 में निर्दिष्ट है, .1 3.9.1.5 में दिए गए वजीफे के साथ:
char16_tबड़ा पर्याप्त किसी भी UTF-16 कोड इकाई का प्रतिनिधित्व करने के लिए है, और के रूप में एक ही आकार, signedness, और संरेखण हैuint_least16_t; इस प्रकार आकार में कम से कम 16 बिट होना आवश्यक है।char32_tबड़ा पर्याप्त किसी भी UTF-32 कोड इकाई का प्रतिनिधित्व करने के लिए है, और के रूप में एक ही आकार, signedness, और संरेखण हैuint_least32_t; इस प्रकार आकार में कम से कम 32 बिट होना आवश्यक है।
bool आकार
bool का आकार कार्यान्वयन को परिभाषित करता है, और 1 हो सकता है या नहीं।
Wchar_t का आकार
wchar_t , जैसा कि § 3.9.1.5 में निर्दिष्ट है, एक अलग प्रकार है, जिसके मानों की सीमा समर्थित स्थानों के बीच सेट की गई सबसे बड़ी विस्तारित वर्ण की प्रत्येक विशिष्ट कोड इकाई का प्रतिनिधित्व कर सकती है। इसका आकार, हस्ताक्षर, और संरेखण अन्य अभिन्न प्रकारों में से एक के रूप में है, जिसे इसके अंतर्निहित प्रकार के रूप में जाना जाता है। इस प्रकार का आकार कार्यान्वयन-परिभाषित है, जैसा कि .1 5.3.3.1 में निर्दिष्ट है, और उदाहरण के लिए, कम से कम 8, 16, या 32 बिट्स हो सकता है; यदि कोई सिस्टम यूनिकोड का समर्थन करता है, उदाहरण के लिए, wchar_t को कम से कम 32 बिट्स होना आवश्यक है (इस नियम का एक अपवाद विंडोज है, जहां संगतता उद्देश्यों के लिए wchar_t 16 बिट्स है)। यह केवल मामूली रिवाइडिंग के साथ C90 मानक, ISO 9899: 1990 .5 4.1.5 से विरासत में मिला है।
कार्यान्वयन के आधार पर, wchar_t का आकार अक्सर होता है, लेकिन हमेशा नहीं, 8, 16 या 32 बिट्स। इनमें से सबसे आम उदाहरण हैं:
- यूनिक्स और यूनिक्स जैसी प्रणालियों में,
wchar_t32-बिट है, और आमतौर पर UTF-32 के लिए उपयोग किया जाता है। - विंडोज में,
wchar_t16-बिट है, और UTF-16 के लिए उपयोग किया जाता है। - ऐसी प्रणाली पर जिसमें केवल 8-बिट समर्थन है,
wchar_t8 बिट है।
यूनिकोड समर्थन वांछित है, तो इसे उपयोग करने के लिए सिफारिश की है char UTF-8, के लिए char16_t UTF-16, या के लिए char32_t उपयोग करने के बजाए, UTF-32 के लिए wchar_t ।
डेटा मॉडल
जैसा कि ऊपर उल्लेख किया गया है, पूर्णांक प्रकारों की चौड़ाई प्लेटफार्मों के बीच भिन्न हो सकती है। सबसे आम मॉडल निम्नानुसार हैं, बिट्स में निर्दिष्ट आकार:
| नमूना | int | long | सूचक |
|---|---|---|---|
| LP32 (2/4/4) | 16 | 32 | 32 |
| ILP32 (4/4/4) | 32 | 32 | 32 |
| LLP64 (4/4/8) | 32 | 32 | 64 |
| LP64 (4/8/8) | 32 | 64 | 64 |
इन मॉडलों में से:
- 16-बिट विंडोज ने LP32 का उपयोग किया।
- 32-बिट * निक्स सिस्टम (यूनिक्स, लिनक्स, मैक ओएसएक्स, और अन्य यूनिक्स जैसे ओएस) और विंडोज आईएलपी 32 का उपयोग करते हैं।
- 64-बिट विंडोज LLP64 का उपयोग करता है।
- 64-बिट * निक्स सिस्टम LP64 का उपयोग करते हैं।
हालाँकि, ध्यान दें कि ये मॉडल मानक में विशेष रूप से उल्लेखित नहीं हैं।
एक बाइट में बिट्स की संख्या
C ++ में, एक बाइट एक char वस्तु द्वारा कब्जा कर लिया गया स्थान है। बाइट में बिट्स की संख्या CHAR_BIT द्वारा दी गई है, जो कि climits में परिभाषित की climits और कम से कम 8 होना आवश्यक है। जबकि अधिकांश आधुनिक प्रणालियों में 8-बिट बाइट्स होते हैं, और POSIX को CHAR_BIT के ठीक 8 होने की आवश्यकता होती है, कुछ सिस्टम हैं जहाँ CHAR_BIT 8 से अधिक है अर्थात एक ही बाइट में 8, 16, 32 या 64 बिट शामिल हो सकते हैं।
एक सूचक का संख्यात्मक मान
एक पूर्णांक का उपयोग कर के लिए सूचक कास्टिंग का परिणाम reinterpret_cast कार्यान्वयन से परिभाषित है, लेकिन "... जो लोग अंतर्निहित मशीन के संबोधित कर संरचना को पता है unsurprising करने का इरादा है।"
int x = 42;
int* p = &x;
long addr = reinterpret_cast<long>(p);
std::cout << addr << "\n"; // prints some numeric address,
// probably in the architecture's native address format
इसी तरह, पूर्णांक से रूपांतरण द्वारा प्राप्त सूचक भी कार्यान्वयन-परिभाषित है।
पूर्णांक के रूप में पॉइंटर को स्टोर करने का सही तरीका uintptr_t या intptr_t प्रकारों का उपयोग कर रहा है:
// `uintptr_t` was not in C++03. It's in C99, in <stdint.h>, as an optional type
#include <stdint.h>
uintptr_t uip;
// There is an optional `std::uintptr_t` in C++11
#include <cstdint>
std::uintptr_t uip;
C ++ 11 परिभाषा uintptr_t (C99 मानक, 6.3.2.3) के लिए C99 को संदर्भित करता है:
संपत्ति के साथ एक अहस्ताक्षरित पूर्णांक प्रकार जो
voidलिए किसी भी वैध सूचक को इस प्रकार में परिवर्तित किया जा सकता है, फिर वापस सूचक कोvoidबदल दिया जाता है, और परिणाम मूल सूचक के बराबर होगा।
हालांकि, अधिकांश आधुनिक प्लेटफार्मों के लिए, आप एक सपाट पता स्थान मान सकते हैं और uintptr_t पर अंकगणित char * पर अंकगणित के बराबर है, यह किसी भी परिवर्तन को लागू करने के लिए कार्यान्वयन के लिए पूरी तरह से संभव है जब void * को uintptr_t में रूपांतरित किया जा सकता है जब तक कि परिवर्तन नहीं हो सकता उल्टा होने पर uintptr_t से void * कास्टिंग करते समय उलट-पलट करें।
शब्दावली
intptr_tअनुरूप (X / Open System Interfaces) सिस्टम पर,intptr_tऔरuintptr_tप्रकारों की आवश्यकता होती है, अन्यथा वे वैकल्पिक होते हैं।सी मानक के अर्थ के भीतर, फ़ंक्शन ऑब्जेक्ट नहीं हैं; यह सी मानक द्वारा गारंटी नहीं है कि
uintptr_tएक फ़ंक्शन पॉइंटर पकड़ सकता है। वैसे भी POSIX (2.12.3) अनुरूपता की आवश्यकता है कि:सभी फ़ंक्शन पॉइंटर प्रकारों में शून्य के प्रकार पॉइंटर के समान प्रतिनिधित्व होगा। फ़ंक्शन पॉइंटर को शून्य में बदलना * प्रतिनिधित्व को परिवर्तित नहीं करेगा। इस तरह के रूपांतरण से उत्पन्न एक शून्य * मान बिना जानकारी के नुकसान के, एक स्पष्ट कलाकारों का उपयोग करके मूल फ़ंक्शन पॉइंटर प्रकार में वापस परिवर्तित किया जा सकता है।
C99 .17.18.1:
जब टाइप किए गए नाम केवल प्रारंभिक यू की अनुपस्थिति या उपस्थिति में भिन्न होते हैं, तो वे 6.2.5 में वर्णित अनुसार हस्ताक्षरित और अहस्ताक्षरित प्रकारों को निरूपित करेंगे; इन संगत प्रकारों में से एक प्रदान करने वाला कार्यान्वयन अन्य को भी प्रदान करेगा।
uintptr_tसमझ मेंuintptr_tसकता है यदि आप सूचक के बिट्स को चीजें करना चाहते हैं जो आप एक हस्ताक्षरित पूर्णांक के साथ समझदारी से नहीं कर सकते हैं।
संख्यात्मक प्रकार के रेंज
पूर्णांक प्रकारों की श्रेणियां कार्यान्वयन-परिभाषित हैं। शीर्ष लेख <limits> std::numeric_limits<T> प्रदान करता है std::numeric_limits<T> टेम्पलेट जो सभी मौलिक प्रकारों के न्यूनतम और अधिकतम मान प्रदान करता है। मान <climits> और (> = C ++ 11) <cinttypes> हेडर के माध्यम से C मानक द्वारा प्रदान की गई गारंटी को संतुष्ट करते हैं।
-
std::numeric_limits<signed char>::min()SCHAR_MINबराबर है, जो कि -127 से कम या बराबर है। -
std::numeric_limits<signed char>::max()SCHAR_MAXबराबर है, जो 127 से अधिक या उसके बराबर है। -
std::numeric_limits<unsigned char>::max()बराबरUCHAR_MAX, जो 255 से अधिक या बराबर है। -
std::numeric_limits<short>::min()SHRT_MINबराबर है, जोSHRT_MINसे कम या बराबर है। -
std::numeric_limits<short>::max()SHRT_MAXबराबर है, जो किSHRT_MAXसे अधिक या बराबर है। -
std::numeric_limits<unsigned short>::max()USHRT_MAXबराबर है, जो 65535 से अधिक या उसके बराबर है। -
std::numeric_limits<int>::min()INT_MINबराबर है, जोINT_MINसे कम या बराबर है। -
std::numeric_limits<int>::max()बराबरINT_MAX, जो 32767 से अधिक या बराबर है। -
std::numeric_limits<unsigned int>::max()बराबरUINT_MAX, जो 65535 से अधिक या उसके बराबर है। -
std::numeric_limits<long>::min()LONG_MINबराबर है, जोLONG_MINसे कम या बराबर है। -
std::numeric_limits<long>::max()बराबरLONG_MAX, जो 2147483647 से अधिक या बराबर है। -
std::numeric_limits<unsigned long>::max()ULONG_MAXबराबर होती है, जो 4294967295 से अधिक या बराबर होती है।
-
std::numeric_limits<long long>::min()LLONG_MINबराबर है, जो किLLONG_MINसे कम या बराबर है। -
std::numeric_limits<long long>::max()बराबरLLONG_MAX, जोLLONG_MAXसे अधिक या बराबर है। -
std::numeric_limits<unsigned long long>::max()ULLONG_MAXstd::numeric_limits<unsigned long long>::max()बराबरULLONG_MAX, जोULLONG_MAXसे अधिक या बराबर है।
फ्लोटिंग प्वाइंट प्रकारों के लिए T , max() अधिकतम परिमित मूल्य है, जबकि min() न्यूनतम सकारात्मक सामान्यीकृत मान है। अतिरिक्त सदस्यों को फ़्लोटिंग-पॉइंट प्रकारों के लिए प्रदान किया जाता है, जो कार्यान्वयन-परिभाषित भी होते हैं, लेकिन <cfloat> हेडर के माध्यम से सी मानक द्वारा प्रदान की गई कुछ गारंटियों को संतुष्ट करते हैं।
- सदस्य
digits10परिशुद्धता के दशमलव अंकों की संख्या देता है।-
std::numeric_limits<float>::digits10FLT_DIG,std::numeric_limits<float>::digits10बराबर है, जो कम से कम 6 है। -
std::numeric_limits<double>::digits10DBL_DIG,std::numeric_limits<double>::digits10बराबर है, जो कम से कम 10 है। -
std::numeric_limits<long double>::digits10LDBL_DIG,std::numeric_limits<long double>::digits10बराबर है, जो कम से कम 10 है।
-
- सदस्य
min_exponent10न्यूनतम नकारात्मक E है जैसे कि 10 शक्ति E सामान्य है।-
std::numeric_limits<float>::min_exponent10FLT_MIN_10_EXP,std::numeric_limits<float>::min_exponent10बराबर है, जो कि सबसे अधिक -37 है। -
std::numeric_limits<double>::min_exponent10बराबरDBL_MIN_10_EXP, जो कि सबसे अधिक -37 है।std::numeric_limits<long double>::min_exponent10LDBL_MIN_10_EXP,std::numeric_limits<long double>::min_exponent10बराबर है, जो कि सबसे अधिक -37 है।
-
- सदस्य
max_exponent10अधिकतम E है जो कि 10 से E शक्ति परिमित है।-
std::numeric_limits<float>::max_exponent10के बराबर होती हैFLT_MIN_10_EXPहै, जो कम से कम 37 है। -
std::numeric_limits<double>::max_exponent10के बराबर होती हैDBL_MIN_10_EXPहै, जो कम से कम 37 है। -
std::numeric_limits<long double>::max_exponent10LDBL_MIN_10_EXP,std::numeric_limits<long double>::max_exponent10बराबर है, जो कम से कम 37 है।
-
- यदि सदस्य
is_iec559सत्य है, तो प्रकार IEC 559 / IEEE 754 के अनुरूप है, और इसलिए इसकी सीमा उस मानक से निर्धारित होती है।
फ्लोटिंग पॉइंट प्रकारों का मान प्रतिनिधित्व
मानक कि आवश्यकता long double के रूप में ज्यादा सटीक रूप में कम से कम प्रदान करता है double है, जो के रूप में ज्यादा सटीक रूप में कम से कम प्रदान करता है float ; और यह कि एक long double किसी भी मूल्य का प्रतिनिधित्व कर सकता है जो एक double का प्रतिनिधित्व कर सकता है, जबकि एक double किसी भी मूल्य का प्रतिनिधित्व कर सकता है जो एक float का प्रतिनिधित्व कर सकता है। प्रतिनिधित्व के विवरण, हालांकि, कार्यान्वयन-परिभाषित हैं।
एक फ्लोटिंग पॉइंट टाइप T , std::numeric_limits<T>::radix T के प्रतिनिधित्व द्वारा प्रयुक्त std::numeric_limits<T>::radix निर्दिष्ट करता है।
यदि std::numeric_limits<T>::is_iec559 सत्य है, तो T का प्रतिनिधित्व IEC 559 / IEEE 754 द्वारा परिभाषित स्वरूपों में से एक से मेल खाता है।
पूर्णांक से हस्ताक्षरित पूर्णांक में परिवर्तित करते समय अतिप्रवाह
जब या तो हस्ताक्षरित या अहस्ताक्षरित पूर्णांक को एक पूर्णांक पूर्णांक प्रकार में परिवर्तित किया जाता है, और इसका मान गंतव्य प्रकार में प्रतिनिधित्व करने योग्य नहीं होता है, तो उत्पादित मूल्य कार्यान्वयन-परिभाषित होता है। उदाहरण:
// Suppose that on this implementation, the range of signed char is -128 to +127 and
// the range of unsigned char is 0 to 255
int x = 12345;
signed char sc = x; // sc has an implementation-defined value
unsigned char uc = x; // uc is initialized to 57 (i.e., 12345 modulo 256)
किसी एनम के प्रकार (और इसलिए आकार) को समझना
यदि अंतर्निहित प्रकार स्पष्ट रूप से एक अज्ञात गणना के लिए निर्दिष्ट नहीं है, तो इसे कार्यान्वयन-परिभाषित तरीके से निर्धारित किया जाता है।
enum E {
RED,
GREEN,
BLUE,
};
using T = std::underlying_type<E>::type; // implementation-defined
हालांकि, मानक नहीं की तुलना में बड़ा होने के लिए एक गणना के अंतर्निहित प्रकार की आवश्यकता होती है int जब तक दोनों int और unsigned int गणन के सभी मूल्यों का प्रतिनिधित्व करने में असमर्थ हैं। इसलिए, उपरोक्त कोड में, कुछ उदाहरण देने के लिए T , int , unsigned int , या short , लेकिन long long नहीं हो सकता है।
नोट एक enum एक ही आकार (के रूप में द्वारा दिया है कि sizeof उसके अंतर्निहित प्रकार के रूप में)।