क्या एक `लंबे` प्रतिबंध का मतलब है?


109

आज के क्रॉस-प्लेटफ़ॉर्म C ++ (या C) दुनिया में हमारे पास :

Data model  | short |   int |   long | long long | pointers/size_t  | Sample operating systems
... 
LLP64/IL32P64   16      32      32     64           64                Microsoft Windows (x86-64 and IA-64)
LP64/I32LP64    16      32      64     64           64                Most Unix and Unix-like systems, e.g. Solaris, Linux, BSD, and OS X; z/OS
...

आज इसका क्या मतलब है, यह है कि किसी भी "सामान्य" (हस्ताक्षरित) पूर्णांक के लिए, intपर्याप्त होगा और संभवतः C ++ एप्लिकेशन कोड लिखते समय डिफ़ॉल्ट पूर्णांक प्रकार के रूप में उपयोग किया जा सकता है। यह भी होगा - वर्तमान व्यावहारिक उद्देश्यों के लिए - प्लेटफार्मों में एक सुसंगत आकार है।

Iff के उपयोग के मामले में कम से कम 64 बिट्स की आवश्यकता होती है, हम आज का उपयोग कर सकते हैं long long, हालांकि संभवतः बिटनेस-निर्दिष्ट प्रकारों में से एक का उपयोग करके या __int64प्रकार अधिक समझ में आ सकता है।

यह longबीच में छोड़ देता है, और हम longअपने एप्लिकेशन कोड के उपयोग पर एकमुश्त प्रतिबंध लगाने पर विचार कर रहे हैं

क्या यह समझ में आता है , या longआधुनिक C ++ (या C) कोड का उपयोग करने के लिए कोई मामला है जिसे क्रॉस प्लेटफॉर्म चलाना है? (प्लेटफ़ॉर्म डेस्कटॉप, मोबाइल डिवाइस, लेकिन माइक्रो-कंट्रोलर, डीएसपी आदि जैसी चीजें नहीं हैं)


संभवतः दिलचस्प पृष्ठभूमि लिंक:


14
आप लंबे समय तक उपयोग करने वाले पुस्तकालयों के लिए कॉल से कैसे निपटेंगे?
.ngel

14
long32 बिट्स की गारंटी देने का एकमात्र तरीका है। int16 बिट्स हो सकते हैं इसलिए कुछ अनुप्रयोगों के लिए यह पर्याप्त नहीं है। हां, intआधुनिक संकलक पर कभी-कभी 16 बिट्स होते हैं। हां, लोग माइक्रोकंट्रोलर पर सॉफ्टवेयर लिखते हैं। मैं बहस चाहते हैं और अधिक लोगों को सॉफ्टवेयर के Arduinos आदि वृद्धि का उल्लेख नहीं करने के लिए iPhone और Android उपकरणों की वृद्धि के साथ पीसी पर से माइक्रोकंट्रोलर्स के बारे में अधिक उपयोगकर्ताओं है कि लिखने
slebetman

53
क्यों नहीं चार, लघु, int, लंबे और लंबे समय तक प्रतिबंध लगाते हैं, और [u] intXX_t प्रकारों का उपयोग करते हैं?
इमिविस

7
@slebetman मैंने थोड़ा गहरा खोदा, यह प्रतीत होता है कि आवश्यकता अभी भी जगह में है, हालांकि .93.9.1.3 में छिपी हुई है जहां C ++ मानक बताता है: "हस्ताक्षरित और अहस्ताक्षरित पूर्णांक प्रकार C मानक, खंड 5.2 में दिए गए अवरोधों को संतुष्ट करेंगे। 4.2.1। " और सी मानक में .25.2.4.2.1 यह न्यूनतम सीमा बताता है, ठीक उसी तरह जैसा आपने लिखा था। आप बिलकुल सही थे। :) स्पष्ट रूप से C ++ मानक की एक प्रति के मालिक हैं, पर्याप्त नहीं है, एक को C मानक की प्रति भी खोजने की आवश्यकता है।
टॉमी एंडरसन

11
आप DOSBox / टर्बो C ++ दुनिया को याद कर रहे हैं जिसमें intअभी भी बहुत अधिक 16 बिट्स हैं। मुझे यह कहने से नफरत है, लेकिन अगर आप "आज के क्रॉस-प्लेटफॉर्म वर्ल्ड" के बारे में लिखने जा रहे हैं, तो आप पूरे भारतीय उपमहाद्वीप को नजरअंदाज नहीं कर सकते।
को ऑर्बिट में हल्की

जवाबों:


17

longआज उपयोग करने का एकमात्र कारण यह है कि इसका उपयोग करने वाले बाहरी इंटरफ़ेस को कॉल या कार्यान्वित करते समय।

जैसा कि आप अपनी पोस्ट में कहते हैं कि आज सभी प्रमुख डेस्कटॉप / सर्वर / मोबाइल प्लेटफॉर्म पर लघु और int में यथोचित रूप से स्थिर विशेषताएँ हैं और मैं इसके लिए कोई कारण नहीं देखता कि निकट भविष्य में बदल जाए। इसलिए मैं सामान्य रूप से उनसे बचने के लिए बहुत कम कारण देखता हूं।

longदूसरी ओर एक गड़बड़ है। सभी 32-बिट सिस्टम पर मुझे इसके बारे में पता है, निम्नलिखित विशेषताएं थीं।

  1. यह आकार में बिल्कुल 32-बिट था।
  2. यह एक स्मृति पते के समान आकार था।
  3. यह डेटा की सबसे बड़ी इकाई के समान आकार का था जिसे एक सामान्य रजिस्टर में रखा जा सकता था और एक निर्देश के साथ काम किया जा सकता था।

इनमें से एक या अधिक विशेषताओं के आधार पर बड़ी मात्रा में कोड लिखा गया था। हालाँकि 64-बिट के लिए कदम के साथ उन सभी को संरक्षित करना संभव नहीं था। यूनिक्स जैसे प्लेटफॉर्म LP64 के लिए गए जो कि विशेषताओं 2 और 3 को विशेषता की कीमत पर संरक्षित करते हैं। Win64 LLP64 के लिए गए, जो कि विशेषताओं 1 की कीमत पर विशेषता 1 को संरक्षित करते हैं और 3. परिणाम है कि आप अब उन विशेषताओं में से किसी पर भरोसा नहीं कर सकते हैं और IMO उपयोग करने के लिए बहुत कम कारण छोड़ता है long

यदि आप एक प्रकार चाहते हैं जो आकार में बिल्कुल 32-बिट्स का उपयोग करें int32_t

यदि आप एक प्रकार चाहते हैं जो कि एक पॉइंटर के समान आकार है जिसे आपको intptr_t(या बेहतर uintptr_t) उपयोग करना चाहिए ।

यदि आप एक प्रकार चाहते हैं जो कि सबसे बड़ा आइटम है जिसे एक ही रजिस्टर / निर्देश में काम किया जा सकता है तो दुर्भाग्य से मुझे नहीं लगता कि मानक एक प्रदान करता है। size_tअधिकांश सामान्य प्लेटफार्मों पर सही होना चाहिए, लेकिन यह x32 पर नहीं होगा ।


पुनश्च

मैं "तेज" या "कम से कम" प्रकारों से परेशान नहीं होता। "कम से कम" प्रकार केवल तभी मायने रखता है जब आप पोर्टेबिलिटी के बारे में वास्तव में वास्तुशिल्प अस्पष्ट करते हैं CHAR_BIT != 8। व्यवहार में "तेज" प्रकारों का आकार बहुत ही मनमाना लगता है। लिनक्स उन्हें सूचक के रूप में कम से कम एक ही आकार का लगता है, जो कि 64-बिट प्लेटफार्मों पर तेजी से 32-बिट समर्थन जैसे x86-64 और arm64 के साथ मूर्खतापूर्ण है। IIRC iOS उन्हें यथासंभव छोटा बनाता है। मुझे यकीन नहीं है कि अन्य सिस्टम क्या करते हैं।


पी पी एस

उपयोग करने का एक कारण unsigned long(लेकिन सादा नहीं long) है क्योंकि यह मोडुलो व्यवहार करने के लिए महत्वपूर्ण है। दुर्भाग्यवश C के खराब होने के कारण पदोन्नति के नियम बिना आकार के छोटे intहैं, जिनके पास modulo व्यवहार नहीं है।

सभी प्रमुख प्लेटफार्मों पर आज uint32_tएक ही आकार या इंट से बड़ा है और इसलिए मॉडुलो व्यवहार है। हालाँकि ऐतिहासिक रूप से वहाँ रहे हैं और सैद्धांतिक रूप से भविष्य के प्लेटफार्मों में हो सकते हैं जहां int64-बिट है और इसलिए uint32_tमॉडुलो व्यवहार नहीं है।

व्यक्तिगत रूप से मैं कहूंगा कि अपने समीकरणों की शुरुआत में "1u *" या "0u +" का उपयोग करके मॉडुलो व्यवहार के लिए मजबूर करने की आदत में बेहतर होगा क्योंकि यह किसी भी प्रकार के अहस्ताक्षरित प्रकार के लिए काम करेगा।


1
"निर्दिष्ट-आकार" प्रकार के सभी अधिक उपयोगी होंगे यदि वे शब्दार्थ निर्दिष्ट कर सकते हैं जो अंतर्निहित प्रकारों से भिन्न होते हैं। उदाहरण के लिए, एक प्रकार का होना उपयोगी होगा, जो कि "int" के आकार की परवाह किए बिना mod-65536 अंकगणितीय का उपयोग करेगा, साथ ही एक प्रकार जो संख्या 0 से 65535 तक रखने में सक्षम होगा, लेकिन मनमाने ढंग से और आवश्यक रूप से लगातार सक्षम नहीं हो सकता है। उससे बड़ी संख्या धारण करने की। अधिकांश मशीनों पर किस आकार का प्रकार सबसे तेज़ होगा, यह संदर्भ पर निर्भर करता है, इसलिए संकलक को मनमाने ढंग से पिक करने में सक्षम होने के कारण गति के लिए इष्टतम होगा।
सुपरकैट

204

जैसा कि आप अपने प्रश्न में उल्लेख करते हैं, आधुनिक सॉफ्टवेयर इंटरनेट पर प्लेटफार्मों और प्रणालियों के बीच अंतर करने के बारे में है। C और C ++ मानक पूर्णांक प्रकार के आकारों के लिए रेंज देते हैं, विशिष्ट आकार नहीं (जावा और C # जैसी भाषाओं के विपरीत)।

यह सुनिश्चित करने के लिए कि विभिन्न प्लेटफार्मों पर संकलित आपका सॉफ़्टवेयर समान डेटा के साथ काम करता है और यह सुनिश्चित करने के लिए कि अन्य सॉफ़्टवेयर समान आकार का उपयोग करके आपके सॉफ़्टवेयर के साथ सहभागिता कर सकते हैं, आपको निश्चित आकार के पूर्णांक का उपयोग करना चाहिए।

वह दर्ज करें <cstdint>जो बिल्कुल ऐसा प्रदान करता है और एक मानक शीर्षलेख है जिसे प्रदान करने के लिए सभी संकलक और मानक पुस्तकालय प्लेटफार्मों की आवश्यकता होती है। नोट: यह शीर्षलेख केवल C ++ 11 के रूप में आवश्यक था, लेकिन कई पुराने पुस्तकालय कार्यान्वयन ने इसे प्रदान किया।

64 बिट अहस्ताक्षरित पूर्णांक चाहते हैं? का उपयोग करें uint64_t। 32 बिट पूर्णांक पर हस्ताक्षर किए? का उपयोग करें int32_t। जबकि हेडर के प्रकार वैकल्पिक हैं, आधुनिक प्लेटफार्मों को उस हेडर में परिभाषित सभी प्रकारों का समर्थन करना चाहिए।

कभी-कभी एक विशिष्ट बिट चौड़ाई की आवश्यकता होती है, उदाहरण के लिए, अन्य प्रणालियों के साथ संचार के लिए उपयोग किए जाने वाले डेटा संरचना में। दूसरी बार ऐसा नहीं है। कम सख्त स्थितियों के लिए, <cstdint>प्रकार प्रदान करता है जो एक न्यूनतम चौड़ाई है।

कम से कम वेरिएंट हैं: int_leastXX_tन्यूनतम XX बिट्स का पूर्णांक प्रकार होगा। यह सबसे छोटे प्रकार का उपयोग करेगा जो XX बिट प्रदान करता है, लेकिन प्रकार को बिट की निर्दिष्ट संख्या से बड़ा होने की अनुमति है। व्यवहार में, ये आम तौर पर ऊपर वर्णित प्रकारों के समान होते हैं जो सटीक संख्या में बिट्स देते हैं।

तेजी से वेरिएंट भी हैं : int_fastXX_tकम से कम XX बिट्स हैं, लेकिन एक प्रकार का उपयोग करना चाहिए जो किसी विशेष प्लेटफॉर्म पर तेजी से प्रदर्शन करता है। इस संदर्भ में "तेज" की परिभाषा अनिर्दिष्ट है। हालाँकि, व्यवहार में, इसका आमतौर पर मतलब है कि सीपीयू के रजिस्टर आकार की तुलना में छोटा एक प्रकार सीपीयू के रजिस्टर आकार का एक प्रकार हो सकता है। उदाहरण के लिए, विज़ुअल C ++ 2015 का हेडर निर्दिष्ट करता int_fast16_tहै कि 32 बिट पूर्णांक है क्योंकि 32 बिट अंकगणितीय x86 पर 16 बिट अंकगणित की तुलना में अधिक तेज़ है।

यह सब महत्वपूर्ण है क्योंकि आपको उन प्रकारों का उपयोग करने में सक्षम होना चाहिए जो आपके कार्यक्रम को मंच की परवाह किए बिना गणना के परिणामों को पकड़ सकते हैं। यदि कोई प्रोग्राम एक प्लेटफ़ॉर्म पर सही परिणाम देता है, लेकिन पूर्णांक ओवरफ़्लो में अंतर के कारण दूसरे पर गलत परिणाम आता है, तो यह खराब है। मानक पूर्णांक प्रकारों का उपयोग करके, आप गारंटी देते हैं कि विभिन्न प्लेटफार्मों पर परिणाम पूर्णांक के आकार के संबंध में समान होंगे (बेशक पूर्णांक चौड़ाई के अलावा प्लेटफार्मों के बीच अन्य अंतर हो सकते हैं)।

तो हाँ, longआधुनिक C ++ कोड पर प्रतिबंध लगाया जाना चाहिए। तो चाहिए int, shortऔर long long


20
मेरी इच्छा है कि मेरे पास कुछ और वोट करने के लिए पांच अन्य खाते हैं।
स्टीवन बर्नैप

4
+1, मैंने कुछ अजीब मेमोरी त्रुटियों से निपटा है जो केवल तब होता है जब एक संरचना का आकार इस बात पर निर्भर करता है कि आप किस कंप्यूटर पर संकलन कर रहे हैं।
जोशुआ स्नाइडर

9
@Wildcard यह एक C हैडर है जो C ++ का भी हिस्सा है: इस पर "c" उपसर्ग देखें। C ++ संकलन इकाई में d stdहोने पर टाइपपैड्स को नेमस्पेस में रखने का भी कोई तरीका है #include, लेकिन मैंने जो दस्तावेज़ीकरण जोड़ा है, वह इसका उल्लेख नहीं करता है और विज़ुअल स्टूडियो को इस बात की परवाह नहीं है कि मैं उन्हें कैसे एक्सेस करता हूं।

11
प्रतिबंध लगाना int... अत्यधिक हो सकता है? (मुझे लगता है कि अगर कोड को सभी अस्पष्ट (और इतना अस्पष्ट नहीं) प्लेटफार्मों पर बेहद पोर्टेबल होना चाहिए, तो "ऐप कोड" के लिए इसे प्रतिबंधित करना हमारे देवताओं के साथ बहुत अच्छा नहीं बैठ सकता है।
मार्टिन बा

5
@Snowman #include <cstdint>को टाइप करने की आवश्यकता है std::(और अफसोस की बात है) वैकल्पिक रूप से उन्हें वैश्विक नाम स्थान में रखने की भी अनुमति है। #include <stdint.h>बिलकुल दीप्ति है। यही बात सी हेडर के किसी अन्य जोड़े पर भी लागू होती है। देखें: stackoverflow.com/a/13643019/2757035 मैं चाहता हूं कि मानक को प्रत्येक को अपने संबंधित नाम स्थान को प्रभावित करने के लिए केवल आवश्यक था - बल्कि कुछ कार्यान्वयनों द्वारा स्थापित गरीब सम्मेलनों के लिए बकसुआ के बजाय - लेकिन ठीक है, यहाँ हम हैं।
अंडरस्कोर_ड

38

नहीं, बिल्ट पूर्णांक प्रकारों पर प्रतिबंध लगाना बेतुका होगा। हालांकि, उनके साथ दुर्व्यवहार नहीं किया जाना चाहिए।

यदि आपको एक पूर्णांक की आवश्यकता है जो कि वास्तव में एन बिट्स चौड़ा है, तो उपयोग करें (या यदि आपको संस्करण की आवश्यकता है )। 32 बिट पूर्णांक के रूप में और 64 बिट पूर्णांक के रूप में सोचना सिर्फ गलत है। यह आपके वर्तमान प्लेटफार्मों पर ऐसा हो सकता है लेकिन यह कार्यान्वयन-परिभाषित व्यवहार पर निर्भर है।std::intN_tstd::uintN_tunsignedintlong long

निश्चित-चौड़ाई पूर्णांक प्रकारों का उपयोग करना अन्य तकनीकों के साथ अंतर-संचालन के लिए भी उपयोगी है। उदाहरण के लिए, यदि आपके आवेदन के कुछ हिस्से जावा और अन्य में C ++ में लिखे गए हैं, तो आप शायद पूर्णांक प्रकारों का मिलान करना चाहेंगे ताकि आपको लगातार परिणाम मिलें। (अभी भी ध्यान रखें कि जावा में अतिप्रवाह में अच्छी तरह से परिभाषित अर्थ-विज्ञान है जबकि signedC ++ में अतिप्रवाह अपरिभाषित व्यवहार है इसलिए स्थिरता एक उच्च लक्ष्य है।) विभिन्न कंप्यूटिंग मेजबानों के बीच डेटा का आदान-प्रदान करते समय वे भी अमूल्य होंगे।

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

तो, बिलिन प्रकारों का उपयोग कब करना है? ठीक है, चूंकि मानक उनकी चौड़ाई को ठीक से निर्दिष्ट नहीं करता है, जब आप वास्तविक बिट चौड़ाई के बारे में नहीं बल्कि अन्य विशेषताओं के बारे में परवाह करते हैं तो उनका उपयोग करें ।

A charसबसे छोटा पूर्णांक है जो हार्डवेयर द्वारा पता करने योग्य है। भाषा वास्तव में आपको मनमानी स्मृति को अलियास करने के लिए इसका उपयोग करने के लिए मजबूर करती है। यह (संकीर्ण) चरित्र तारों का प्रतिनिधित्व करने के लिए एकमात्र व्यवहार्य प्रकार भी है।

एक intआम तौर पर सबसे तेजी से टाइप मशीन संभाल कर सकते हैं होगा। यह इतना चौड़ा होगा कि इसे एक ही निर्देश के साथ लोड और संग्रहीत किया जा सकता है (बिना मास्क या शिफ्ट बिट्स के) और पर्याप्त संकीर्ण ताकि इसे (सबसे) कुशल हार्डवेयर निर्देशों के साथ संचालित किया जा सके। इसलिए, intडेटा को पारित करने और अंकगणित करने के लिए एक आदर्श विकल्प है जब अतिप्रवाह एक चिंता का विषय नहीं है। उदाहरण के लिए, डिफ़ॉल्ट अंतर्निहित प्रकार की गणना है int। इसे केवल 32 बिट पूर्णांक में परिवर्तित न करें क्योंकि आप कर सकते हैं। इसके अलावा, अगर आपके पास एक मूल्य है जो केवल -1, 0 और 1 हो सकता है, तो एintएक सही विकल्प है, जब तक कि आप उनमें से विशाल सरणियों को संग्रहीत नहीं करने जा रहे हैं, जिस स्थिति में आप व्यक्तिगत तत्वों तक पहुँचने के लिए उच्च मूल्य का भुगतान करने की कीमत पर अधिक कॉम्पैक्ट डेटा प्रकार का उपयोग करना चाह सकते हैं। अधिक कुशल कैशिंग की संभावना है कि वे इनके लिए भुगतान करेंगे। कई ऑपरेटिंग सिस्टम फ़ंक्शंस के संदर्भ में भी परिभाषित किए गए हैं int। उनके तर्कों और परिणामों को आगे और पीछे करना मूर्खतापूर्ण होगा। यह सब संभवत: अतिप्रवाह त्रुटियों का परिचय दे सकता है ।

longआमतौर पर एक मशीन के निर्देशों के साथ संभाला जाने वाला सबसे चौड़ा प्रकार होगा। यह unsigned longकच्चे डेटा और सभी प्रकार के बिट हेरफेर सामान से निपटने के लिए विशेष रूप से बहुत आकर्षक बनाता है । उदाहरण के लिए, मैं unsigned longबिट-वेक्टर के कार्यान्वयन में देखने की अपेक्षा करूंगा । यदि कोड ध्यान से लिखा गया है, तो इससे कोई फर्क नहीं पड़ता कि वास्तव में प्रकार कितना चौड़ा है (क्योंकि कोड स्वचालित रूप से अनुकूलित होगा)। उन प्लेटफ़ॉर्मों पर जहां मूल मशीन-शब्द 32 बिट है, बिट-वेक्टर का बैकिंग एरे होने का एक सरणी हैunsigned32 बिट पूर्णांक सबसे अधिक वांछनीय है क्योंकि यह 64 बिट प्रकार का उपयोग करने के लिए मूर्खतापूर्ण होगा जो कि अनावश्यक निर्देशों को केवल फिर से स्थानांतरित करने और मास्क करने के लिए महंगे निर्देशों के माध्यम से लोड किया जाना है। दूसरी ओर, यदि प्लेटफ़ॉर्म का मूल शब्द आकार 64 बिट है, तो मुझे उस प्रकार की एक सरणी चाहिए, क्योंकि इसका मतलब है कि "पहले सेट को खोजें" जैसे ऑपरेशन दो बार तेजी से चल सकते हैं। तो जिस longडेटा प्रकार का आप वर्णन कर रहे हैं, उसका "समस्या" , इसका आकार प्लेटफ़ॉर्म से प्लेटफ़ॉर्म तक भिन्न होता है, वास्तव में एक ऐसी सुविधा है जिसे अच्छे उपयोग में लाया जा सकता है। यह केवल एक समस्या बन जाती है यदि आप बिलिन प्रकारों के बारे में सोचते हैं जो एक निश्चित बिट चौड़ाई के प्रकार हैं, जो कि वे बस नहीं करते हैं।

char, intऔर longऊपर वर्णित के रूप में बहुत उपयोगी प्रकार हैं। shortऔर long longलगभग उतने उपयोगी नहीं हैं क्योंकि उनके शब्दार्थ बहुत कम स्पष्ट हैं।


4
ओपी ने विशेष रूप से longविंडोज और यूनिक्स के बीच के अंतर को कहा । मुझे गलतफहमी हो सकती है, लेकिन longएक "समस्या" के बजाय एक "विशेषता" के आकार में अंतर का आपका वर्णन मेरे लिए 32 और 64 बिट डेटा मॉडल की तुलना करने के लिए समझ में आता है, लेकिन इस विशेष तुलना के लिए नहीं। जिस विशेष मामले में यह सवाल पूछा गया है, क्या यह वास्तव में एक विशेषता है? या यह अन्य स्थितियों में एक विशेषता है (जो कि सामान्य रूप से है), और इस मामले में हानिरहित है?
दान गेट्ज़

3
@ 5gon12eder: समस्या यह है कि कोड के व्यवहार को "int" के आकार से स्वतंत्र होने की अनुमति देने के उद्देश्य से uint32_t जैसे प्रकार बनाए गए थे, लेकिन एक प्रकार की कमी जिसका अर्थ होगा "एक uint32_t की तरह व्यवहार करना" बिट सिस्टम "लेखन कोड बनाता है जिसका व्यवहार" int "के आकार से स्वतंत्र रूप से स्वतंत्र है कोड लिखने की तुलना में बहुत कठिन है जो लगभग सही है।
सुपरकैट

3
हाँ, मुझे पता है ... कि कोस कहाँ से आया था। मूल लेखकों ने सिर्फ पट्टे के प्रतिरोध का रास्ता अपनाया क्योंकि जब उन्होंने कोड लिखा था, तो 32-बिट ओएस एक दशक से अधिक दूर थे।
स्टीवन बर्नैप

8
@ 5gon12eder अफसोस की बात है, सुपरकैट सही है। सटीक-चौड़ाई के सभी प्रकार "बस टाइप किए गए" हैं और पूर्णांक पदोन्नति नियमों में से कोई भी नोटिस नहीं लिया गया है, जिसका अर्थ है कि uint32_tमानों पर अंकगणित को हस्ताक्षरित के रूप में बाहर किया जाएगा , int-एक मंच पर अंकगणित अंकगणित की तुलना intमें व्यापक है uint32_t। (आज के एबीआई के साथ यह काफी हद तक एक मुद्दा बनने की संभावना है uint16_t।)
zwol

9
1, एक विस्तृत जवाब के लिए धन्यवाद। लेकिन: ओह प्रिय। आपका लंबा पैराग्राफ: " longआमतौर पर सबसे चौड़ा प्रकार होगा जिसे एकल मशीन निर्देशों के साथ संभाला जा सकता है ..." - और यह बिल्कुल गलत है । विंडोज डेटा मॉडल को देखें। IMHO, आपका पूरा निम्नलिखित उदाहरण टूट जाता है, क्योंकि x64 पर विंडोज लंबा अभी भी 32 बिट है।
मार्टिन बा

6

एक और जवाब पहले से ही cstdint प्रकार और कम-ज्ञात भिन्नताओं पर विस्तृत है।

मैं उसमें जोड़ना चाहूंगा:

डोमेन-विशिष्ट प्रकार के नामों का उपयोग करें

अर्थात्, अपने मापदंडों और चर को घोषित न करें uint32_t(निश्चित रूप से नहीं long!), लेकिन नाम जैसे कि channel_id_type, room_count_typeआदि।

पुस्तकालयों के बारे में

3 पार्टी लाइब्रेरियों का उपयोग longया व्हाट्सएप परेशान कर सकता है, खासकर अगर उन पर संदर्भ या संकेत के रूप में उपयोग किया जाता है।

सबसे अच्छी बात रैपर बनाना है।

मेरी रणनीति, सामान्य तौर पर, कास्ट-जैसे कार्यों का एक सेट बनाना है जिसका उपयोग किया जाएगा। वे केवल उन प्रकारों को स्वीकार करने के लिए अधिभारित होते हैं जो वास्तव में संबंधित प्रकारों के साथ मेल खाते हैं, साथ ही जो कुछ भी सूचक आदि आपकी ज़रूरतों को बदलते हैं। वे ओएस / संकलक / सेटिंग्स के लिए विशिष्ट परिभाषित किए गए हैं। इससे आप चेतावनी निकाल सकते हैं और फिर भी यह सुनिश्चित कर सकते हैं कि केवल "सही" रूपांतरण का उपयोग किया जाए।

channel_id_type cid_out;
...
SomeLibFoo (same_thing_really<int*>(&cid_out));

विशेष रूप से, 32 बिट्स का निर्माण करने वाले विभिन्न आदिम प्रकारों के साथ, आपकी पसंद को कैसे int32_tपरिभाषित किया जाता है, यह लाइब्रेरी कॉल (उदाहरण के लिए विंडोज पर लंबे समय तक) से मेल नहीं खा सकता है।

कास्ट-जैसे फंक्शन डॉक्यूमेंट्स क्लैश करता है, फंक्शन के पैरामीटर से मेल खाते रिजल्ट पर कंपाइल-टाइम चेकिंग की सुविधा देता है, और अगर वास्तविक टाइप में शामिल वास्तविक आकार से मेल खाता हो तो ही कोई चेतावनी या त्रुटि निकालता है । यह है, यह अतिभारित और परिभाषित है अगर मैं (विंडोज पर) एक int*या एक से गुजरता हूं long*और अन्यथा संकलन-समय त्रुटि देता है।

इसलिए, यदि लाइब्रेरी अपडेट की गई है या कोई व्यक्ति बदल गया channel_id_typeहै, तो यह सत्यापित होना जारी है।


नीचे (टिप्पणी के बिना) क्यों?
JDługosz

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