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_t
32-बिट है, और आमतौर पर UTF-32 के लिए उपयोग किया जाता है। - विंडोज में,
wchar_t
16-बिट है, और UTF-16 के लिए उपयोग किया जाता है। - ऐसी प्रणाली पर जिसमें केवल 8-बिट समर्थन है,
wchar_t
8 बिट है।
यूनिकोड समर्थन वांछित है, तो इसे उपयोग करने के लिए सिफारिश की है 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_MAX
std::numeric_limits<unsigned long long>::max()
बराबरULLONG_MAX
, जोULLONG_MAX
से अधिक या बराबर है।
फ्लोटिंग प्वाइंट प्रकारों के लिए T
, max()
अधिकतम परिमित मूल्य है, जबकि min()
न्यूनतम सकारात्मक सामान्यीकृत मान है। अतिरिक्त सदस्यों को फ़्लोटिंग-पॉइंट प्रकारों के लिए प्रदान किया जाता है, जो कार्यान्वयन-परिभाषित भी होते हैं, लेकिन <cfloat>
हेडर के माध्यम से सी मानक द्वारा प्रदान की गई कुछ गारंटियों को संतुष्ट करते हैं।
- सदस्य
digits10
परिशुद्धता के दशमलव अंकों की संख्या देता है।-
std::numeric_limits<float>::digits10
FLT_DIG
,std::numeric_limits<float>::digits10
बराबर है, जो कम से कम 6 है। -
std::numeric_limits<double>::digits10
DBL_DIG
,std::numeric_limits<double>::digits10
बराबर है, जो कम से कम 10 है। -
std::numeric_limits<long double>::digits10
LDBL_DIG
,std::numeric_limits<long double>::digits10
बराबर है, जो कम से कम 10 है।
-
- सदस्य
min_exponent10
न्यूनतम नकारात्मक E है जैसे कि 10 शक्ति E सामान्य है।-
std::numeric_limits<float>::min_exponent10
FLT_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_exponent10
LDBL_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_exponent10
LDBL_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
उसके अंतर्निहित प्रकार के रूप में)।