C99 में लंबे समय तक

Jan 10 2021

C99 मानक में उन्होंने पेश किया long long। इसका उद्देश्य क्या है? मेरे (सीमित) सी प्रोग्रामिंग अनुभव में, मैंने केवल एक 4-बाइट इंट और 8-बाइट लंबा देखा है। उदाहरण के लिए, कंपाइलर एक्सप्लोरर से:

यदि longपहले से ही है 8, तो दूसरे long longप्रकार को जोड़ना क्यों आवश्यक है ? यह कंपाइलर / आर्किटेक्चर को क्या करता है?

जवाब

6 chux-ReinstateMonica Jan 10 2021 at 05:36

यदि लंबे समय से पहले से ही 8 है, तो एक और लंबे लंबे प्रकार को जोड़ना क्यों आवश्यक है? यह कंपाइलर / आर्किटेक्चर को क्या करता है?

"यदि लंबे समय से पहले से ही 8 है" तो हमेशा सच नहीं होता है क्योंकि इतना कोड मौजूद है जो 32-बिट longऔर int32 या 16 बिट्स पर निर्भर करता है ।

की आवश्यकता होती है long64-बिट के रूप में कोड ठिकानों टूट जाएगा। यह एक प्रमुख चिंता का विषय है।


फिर भी long32-बिट (और नहीं long long) रहने के लिए मानक 64-बिट पूर्णांकों तक पहुंच बनाने की आवश्यकता नहीं होगी, इसलिए इसके लिए तर्क है long long

की अनुमति दे longके रूप में या तो 32-बिट या 64-बिट (या अन्य) संक्रमण के लिए अनुमति देता है।

विभिन्न कार्य longजैसे / वापसी में गुजरते हैं fseek(), ftell()। वे longबड़े फ़ाइल समर्थन के लिए 32-बिट से अधिक होने का लाभ उठाते हैं ।

अनुशंसित अभ्यास एक व्यापक को प्रोत्साहित करता है long: "जिस प्रकार के लिए उपयोग किया जाना चाहिए size_tऔर ptrdiff_tउससे अधिक पूर्णांक रूपांतरण रैंक नहीं होना चाहिए, signed long intजब तक कि कार्यान्वयन इस वस्तु को आवश्यक बनाने के लिए पर्याप्त रूप से वस्तुओं का समर्थन नहीं करता है।" यह 32-बिट से अधिक मेमोरी साइज से संबंधित है।


शायद भविष्य में एक कार्यान्वयन int/long/long long/intmax_t32/64/128/256 बिट्स के रूप में उपयोग हो सकता है ।

आईएसी, मैं प्रकार चौड़ाई तय देखें intN_tपर लोकप्रियता में वृद्धि हो रही longहै और long long। मैं निश्चित चौड़ाई प्रकार या का उपयोग करते हैं bool, ( unsigned) char, int/ unsigned, size_t, ( u) intmax_tऔर छुट्टी signed char, ( unsigned) short, ( unsigned) long, ( unsigned) long longविशेष मामलों के लिए।

4 dbush Jan 10 2021 at 05:26

C मानक केवल गारंटी देता है कि एक int(कम बोलने वाला) 2 बाइट्स longहो सकता है , एक 4 बाइट्स हो सकता है, और एक long long8 बाइट्स हो सकता है।

वास्तव में, MSVC अभी भी 4 बाइट का उपयोग करता है, longभले ही इसमें 4 बाइट हो int

3 NateEldredge Jan 10 2021 at 05:38

केवल intऔर longफिर, के लिए एकमात्र प्रासंगिक आवश्यकता यह है कि intकम से कम 16 बिट्स longहोने चाहिए और कम से कम 32 बिट्स होने चाहिए। 16- और 32-बिट सिस्टम दोनों में 32-बिट है long, और 1990 के दशक के अंत में 64-बिट मशीनें बहुत कम आम थीं। इसलिए C99 से पहले, प्रोग्रामर 64-बिट पूर्णांक प्रकार उपलब्ध होने पर निर्भर नहीं कर सकते थे। उस समस्या को हल करने से शुरू किया गया था long long, जिसे कम से कम 64 बिट होना आवश्यक है। (मेरा मानना ​​है कि यह पहले से ही जीसीसी और शायद एक विस्तार के रूप में अन्य संकलक द्वारा प्रदान किया गया था)।

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

2 PeterCordes Jan 10 2021 at 10:29

मुझे लगता है कि आपको एहसास नहीं था कि आप सी-चौड़ाई की आवश्यकताओं के काम करने के तरीके के बारे में एक बहुत बड़ी गलत धारणा बना रहे हैं: आईएसओ सी सिर्फ एक न्यूनतम मूल्य-सीमा निर्धारित करता है जैसे कि अनुमति दी गई LONG_MAXऔर LONG_MIN(-2147483647, 8 नहीं क्योंकि आईएसओ सी किसी के पूरक और हस्ताक्षर / परिमाण पर हस्ताक्षर किए गए पूर्णांक की अनुमति देता है, न कि केवल 2 के पूरक।) वास्तविक कार्यान्वयन को व्यापक प्रकार की अनुमति दी जाती है, अक्सर एक रजिस्टर चौड़ाई या ऑपरेंड-आकार का मिलान करने के लिए लक्ष्य मशीन कुशलता से कर सकती है।

स्टैक ओवरफ्लो और अन्य जगहों पर इसके बारे में बहुत कुछ लिखा गया है, जिसे मैं यहां दोहराने की कोशिश नहीं कर रहा हूं। यह सभी देखेंhttps://en.cppreference.com/w/c/language/arithmetic_types


इससे आपको x86-64 सिस्टम V ABI में टाइप-चौड़ाई विकल्पों को देखने की गलती हुई और यह मानकर कि अन्य C कार्यान्वयन समान हैं, मुझे लगता है। x86-64 एक 64-बिट आईएसए है जो कुशलता से 64-बिट पूर्णांक के साथ काम कर सकता है, इसलिए 64-बिट longएक काफी समझदार विकल्प था।

I386 जैसी 32-बिट मशीन के लिए कोई भी sane ABI 64-बिट का उपयोग नहीं करेगा longक्योंकि इसकी आवश्यकता नहीं है, केवल 32-बिट। 64-बिट का उपयोग करने का मतलब होगा कि यह एक ही रजिस्टर में फिट नहीं हो सकता है। संकलन करें -m32, या 32-बिट एआरएम के लिए संकलन करें । Godbolt में AVR और MSP430 के लिए GCC भी है। उन 8-बिट और 16-बिट मशीनों पर, जीसीसी आईएसओ सी (2-बाइट int, आदि) द्वारा अनुमत सबसे छोटी चौड़ाई चुनता है ।

1999 में, x86-64 भी मौजूद नहीं था। (कुछ अन्य 64-बिट आईएसए ने अल्फा की तरह किया)। तो C99 विकल्पों को समझने के लिए इसके लिए 2 मुख्यधारा ABI में से एक को देखना आपको बहुत दूर नहीं जाना है।

बेशक C को एक ऐसे प्रकार की आवश्यकता है जो कम से कम 64-बिट की गारंटी दे, लोगों को ऐसे प्रोग्राम लिखने दे जो कुशलता से 64-बिट पूर्णांक गणित करते हैं।


और BTW, x86-64 32-बिट पूर्णांक सामान को कुशलतापूर्वक 64-बिट के रूप में कर सकता है, कभी-कभी अधिक कुशलता से। तो long64-बिट प्रकार बनाना यकीनन महान नहीं है। कुछ कोड का उपयोग longकरते हैं क्योंकि वे एक प्रकार चाहते हैं जो 32-बिट होना चाहिए, लेकिन इसे व्यापक होने से कोई लाभ नहीं होता है। इस तरह के कोड के लिए, 64-बिट longसिर्फ कैश फुटप्रिंट / मेमोरी बैंडविड्थ, और कोड आकार (आरईएक्स उपसर्ग) बर्बाद करता है। C99 में आदर्श विकल्प होगा int_least32_t, लेकिन यह लंबे समय से टाइप करने के लिए और शायद ही कभी इस्तेमाल किया जाता है।

लेकिन OTOH, longकभी-कभी "सबसे व्यापक कुशल (1-रजिस्टर) प्रकार" होने की उम्मीद है, हालांकि ऐसी कोई गारंटी नहीं है और 32-बिट के साथ Windows x64 जैसे LLP64 ABI ऐसे longनहीं हैं।

कीड़े का एक और पूरा कर सकते हैं C99 int_fast32_tऔर x86-64 सिस्टम V का IMO खराब विकल्प है जो 64-बिट प्रकार बनाता है। (मेरे पास Cpp uint32_fast_t के लिए आधा-लिखित उत्तर है, जो uint64_t को हल करता है, लेकिन एक uint32_t (x86_64) की तुलना में लगभग सभी कार्यों के लिए धीमा है। यह uint64 - t का समाधान क्यों करता है? जिसे मुझे समाप्त करना चाहिए ... int_fast32_t"के लिए क्या उपवास का प्रश्न उठाता है ? " उद्देश्य ", और कई कार्यान्वयन पर यह वह नहीं है जो आप कई मामलों के लिए आशा करेंगे।

यह सभी देखें

  • C ++ - सबसे तेज पूर्णांक प्रकार?
  • X86 ABI के साथ या उसके बिना [u] int_fastN_t प्रकारों को कैसे परिभाषित किया जाना चाहिए?
  • Uint_fast32_t के बजाय uint32_t को क्यों प्राथमिकता दी जाएगी?
  • X86_64 में गुणन के लिए uint_least16_t को uint_fast16_t से अधिक तेज़ क्यों माना जाता है?
  • कंपाइलर अनुकूलन को "int", "कम से कम" और "तेज" गैर-निश्चित चौड़ाई प्रकार C / C ++ के माध्यम से अनुमति दी गई है
old_timer Jan 11 2021 at 06:16

कुछ सीमाएँ हैं, लेकिन संकलक लेखक मानक सी चर प्रकार (चार, लघु, अंतर, लंबा, लंबा लंबा) के लिए लंबाई चुनने के लिए स्वतंत्र है। स्वाभाविक रूप से चारो उस वास्तुकला के लिए एक बाइट बनने जा रहे हैं (सी कंपाइलर के साथ 8 बिट्स हैं)। और स्वाभाविक रूप से आपके पास कुछ बड़ा होने की तुलना में छोटा नहीं हो सकता है, लंबे समय तक एक इंट से छोटा नहीं हो सकता है। लेकिन निश्चित रूप से 1999 तक हमने x86 16 से 32 बिट संक्रमण देखा और उदाहरण के लिए int को कई उपकरणों के साथ 16 से 32 में बदल दिया लेकिन लंबे समय तक 32 बने रहे। बाद में 32 से 64 बिट x86 संक्रमण हुआ और उपकरण के आधार पर प्रकार उपलब्ध थे मदद करने के लिए।

समस्या इसके बहुत पहले से मौजूद थी और इसका समाधान प्रकारों की लंबाई को ठीक करने के लिए नहीं था, वे नियमों के भीतर हैं, आकार के रूप में संकलक लेखकों तक। लेकिन संकलक लेखकों को एक stdint.h फ़ाइल को तैयार करने की आवश्यकता होती है जो उपकरण और लक्ष्य से मेल खाती है (stdint.h एक उपकरण के लिए विशिष्ट है और एक न्यूनतम पर लक्ष्य है और उपकरण का संस्करण हो सकता है और उस उपकरण के लिए विकल्प का निर्माण कर सकता है, आदि)। इसलिए, उदाहरण के लिए, uint32_t हमेशा 32 बिट्स होता है। कुछ लेखक इसे एक दूसरे को लंबे समय तक एक आदि में बदल देंगे। C भाषा चर प्रकार भाषा के प्रति char, short, int, आदि तक सीमित रहती है (uint32_t एक चर प्रकार नहीं है जिसे इसे stdint.h के माध्यम से चर प्रकार में परिवर्तित किया जाता है)। यह समाधान / वर्कअराउंड सभी पागल होने से और भाषा को जीवित रखने का एक तरीका है।

लेखक अक्सर उदाहरण के लिए चुनेंगे कि क्या जीपीआर 16 बिट का इंट 16 बिट है, और यदि 32 बिट 32 बिट और इतने पर हो, लेकिन उन्हें कुछ स्वतंत्रता है।

हां, इसका विशेष रूप से अर्थ है कि यह मानने का कोई कारण नहीं है कि किसी विशेष लक्ष्य के लिए कोई दो उपकरण (उदाहरण के लिए आप जिस कंप्यूटर पर इसे पढ़ रहे हैं) विशेष रूप से इंट और लंबे समय के लिए समान परिभाषाओं का उपयोग करते हैं, और यदि आप कोड लिखना चाहते हैं यह प्लेटफ़ॉर्म जो इन टूल्स के पार पोर्ट कर सकता है (जो इस प्लेटफ़ॉर्म को सपोर्ट करता है) तो stdint.h प्रकारों का उपयोग करें और int, long, etc नहीं ... सबसे निश्चित रूप से यदि आप प्लेटफ़ॉर्म को पार कर रहे हैं msp430 mcu, आर्म mcu, आर्मपॉक्स मशीन , एक x86 आधारित मशीन, कि प्रकार, समान "टूलचैन" के लिए (उदाहरण के लिए ग्नू जीसीसी और बिनुटिल्स), इंट और लॉन्ग के लिए समान परिभाषाएं नहीं हैं, आदि चार और 16 बिट्स, चार और लघु प्रवृत्ति हैं। int और long सबसे भिन्न होते हैं, कभी-कभी एक-दूसरे के समान आकार कभी-कभी अलग-अलग होते हैं, लेकिन बिंदु ग्रहण नहीं करता है।

एक संकलक संस्करण / लक्ष्य / कमांड लाइन विकल्प के लिए, या बाद में समस्याओं को कम करने के लिए stdint मार्ग पर जाने के लिए आकारों का पता लगाना तुच्छ है।