1 पॉइंट द्वारा GN⁺ 2024-10-19 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • P3477R0 C++ में byte के आकार को CHAR_BIT जैसे implementation-defined मान पर छोड़ने के बजाय उसे ठीक 8-bit पर तय करने वाला standard बदलाव प्रस्तावित करता है
  • आधुनिक platforms पहले ही 8-bit byte को आधार मानकर एकरूप हो चुके हैं, और GCC, LLVM, MSVC भी अपने संबंधित defaults या macros को 8 पर रखते हैं
  • POSIX, POSIX.1-2001 से CHAR_BIT == 8 की मांग करता है, और C++20 तथा C23 में two's complement integer representation अपनाने की दिशा भी इसी ओर जाती है
  • non-8-bit byte support भाषा, library और toolchain में छोटे-छोटे exceptions छोड़ता है, और व्यावहारिक आधुनिक C++ उपयोग से मेल न खाने वाला edge case बोझ पैदा करता है
  • PDP-10 या कुछ DSP जैसी अपवादात्मक architectures मौजूद हैं, लेकिन मुख्य प्रश्न यह है कि क्या नए C++ standard को अब भी उनके लिए यह जटिलता बनाए रखनी चाहिए

P3477R0 का बदलाव लक्ष्य

  • C++ में C का CHAR_BIT macro आता है, और फिलहाल यह मान byte में bits की संख्या बताने वाला implementation-defined value है
  • P3477R0 प्रस्ताव देता है कि C++ standard आधिकारिक रूप से byte को 8-bit होने की शर्त लगाए
  • computing के शुरुआती दौर में अलग-अलग byte sizes की flexibility उपयोगी थी, लेकिन प्रस्ताव का आधार यह है कि आधुनिक hardware लगभग पूरी तरह 8-bit byte पर आकर स्थिर हो चुका है

compiler और platform की मौजूदा स्थिति

  • प्रमुख compilers पहले से 8-bit byte को ही व्यावहारिक default मानते हैं
    • GCC default को 8 रखता है, और upstream targets में ऐसा कोई मामला नहीं है जो इस default को बदलता हो
    • LLVM __CHAR_BIT__ को 8 सेट करता है
    • MSVC CHAR_BIT को 8 पर define करता है
  • GCC के पुराने support उदाहरणों में dsp16xx को 2004 में, और 1750a को 2002 में हटाया गया था
  • web search में कुछ external GCC ports दिखते हैं जहां BITS_PER_UNIT 8 नहीं है, लेकिन प्रस्ताव के अनुसार वे आधुनिक C++ से प्रासंगिक नहीं लगते

POSIX और integer representation की दिशा

  • POSIX POSIX.1-2001 से निम्न शर्तें मांगता है
    • byte ठीक 8-bit हो
    • CHAR_BIT 8 हो
    • SCHAR_MAX 127, SCHAR_MIN -128, UCHAR_MAX 255 हों
  • POSIX यह भी बताता है कि int8_t जोड़ने के परिणामस्वरूप 8-bit char और two's complement arithmetic की जरूरत पड़ती है
  • C++20, P0907r4 के बाद, सिर्फ two's complement storage को support करता है, और C23 भी इसी दिशा में चलता है
  • वर्तमान POSIX-compliant operating systems के उदाहरण के रूप में AIX, HP-UX, INTEGRITY, macOS, OpenServer, UnixWare, VxWorks, vz/OS सूचीबद्ध हैं

non-8-bit byte से बची रहने वाली लागत

  • 8-bit byte software और non-8-bit byte software एक-दूसरे के साथ compatible नहीं होते, और ऐसे target के लिए C/C++ code व्यावहारिक रूप से C और C++ की incompatible dialects जैसा हो जाता है
  • non-8-bit byte architecture support भाषा और library के कई हिस्सों में छोटी लेकिन अनावश्यक complexity छोड़ता है
  • compiler और toolchain को ऐसे edge cases का बोझ ढोना पड़ता है जो आधुनिक उपयोग को प्रतिबिंबित नहीं करते
  • नए programmers C++ की इस तरह की असामान्य विशेषताओं से आसानी से भ्रमित हो सकते हैं
  • प्रस्ताव का तर्क है कि कुछ अनुभवी programmers भी ऐसे platforms के लिए “portability” पर समय खर्च करते हैं जो वास्तव में मौजूद ही नहीं हैं

अपवाद architectures और समझौते का विकल्प

  • प्रस्ताव यह मानता है कि non-8-bit byte processors अभी भी मौजूद हैं
  • मुख्य सवाल यह है कि क्या ऐसे processors का modern C++ से कोई वास्तविक संबंध है, और क्या उनके users नए C++ versions अपनाएंगे
  • समझौते के रूप में CHAR_BIT % 8 == 0 की शर्त का विकल्प भी रखा गया है, लेकिन इसका मतलब तभी है जब committee CHAR_BIT को 8 न होते हुए भी 8 के गुणज रखने वाले DSP या अन्य processors का support जारी रखना चाहे
  • PDP-10 चर्चा का विषय है, जबकि PDP-11 के बारे में अलग से बताया गया है कि वह 8-bit byte इस्तेमाल करता है
  • कुछ DSP 24-bit या 32-bit words को “byte” जैसा मानते हैं; ऐसी architectures उस दौर में उचित थीं जब word sizes विविध थीं और byte की अवधारणा standard नहीं हुई थी

standard wording में बदलाव की दिशा

  • intro.memory में byte की परिभाषा बदलकर यह स्पष्ट करने का प्रस्ताव है कि C++ memory model की मूल storage unit byte 8-bit है
  • climits में CHAR_BIT को 8 मानने की दिशा में wording बदलाव प्रस्तावित है
  • cstdint में, क्योंकि byte 8-bit होगा, int8_t, uint8_t जैसे fixed-width integer types और संबंधित macros अब optional नहीं रहेंगे
  • _N_ का उपयोग करने वाले types में, जहां N 8, 16, 32, 64 नहीं है, वहां उन्हें अब भी optional रखा जाएगा
  • localization के भीतर CHAR_BIT == 8 से जुड़े 4 mandates clauses हटाने का बदलाव भी शामिल है

C standard के साथ संबंध

  • प्रस्ताव यह जांचता है कि क्या C++ को non-8-bit byte architectures से जुड़ा रहना चाहिए
  • C committee, C भाषा के लिए, किसी अलग निष्कर्ष पर पहुंच सकती है
  • दोनों committees का aligned होना आदर्श होगा, लेकिन यह प्रस्ताव WG14 और SG22 liaison group से WG21 को जानकारी देने वाले ढांचे के रूप में रखा गया है

1 टिप्पणियां

 
GN⁺ 2024-10-19
Hacker News टिप्पणियां
  • JF की “क्या हम मान सकते हैं कि असली कंप्यूटर वैसे ही काम करते हैं?” सीरीज़ में पहले से signed integers 2's complement होते हैं वाला हिस्सा था: "Signed Integers are Two’s Complement"

    • अगला नंबर शायद यह साफ़ तौर पर लिखने का हो कि floating-point हमेशा IEEE floating-point होता है
      हालांकि ऐसा करने से Linux kernel का यह क्लासिक कोड पुराना पड़ सकता है: https://github.com/torvalds/linux/blob/master/include/math-emu/double.h#L29
  • 1986 में internship के दौरान मैंने 10-bit byte इस्तेमाल करने वाले BBN C/70 पर C code लिखा था; अनुभव भयानक था, और ऐसी machine का मौजूद होना ही नकारात्मक अर्थ में एक cosmic accident था

    • मैंने DECSYSTEM-20 पर code लिखा था, जहां C compiler officially supported नहीं था
      उसमें 36-bit word और 7-bit byte थे, और bytes को word में pack करने पर bits बच जाते थे। ऊपर से मुझे 8-bit format वाले binary data की tape पढ़ने का काम मिला था, तो पूरा बवाल हो गया
    • मैंने Intel Intellivision CPU को program किया था; वह 10-bit decl इस्तेमाल करने वाली अजीब machine थी, और C चलाने लायक powerful नहीं थी
    • मैंने 9-bit byte और 81-bit instructions वाली machine पर, और 6-bit byte वाली machine पर काम किया है, लेकिन दोनों में C compiler नहीं था
    • आजकल FPGA में 10-bit arithmetic सचमुच uncommon नहीं है और comparatively modern products में भी इस्तेमाल होती है
      लेकिन 10-bit C की बात अलग है
  • D ने ये तय करके बड़ी छलांग लगाई: byte 8 bits का है, short 16 bits का, int 32 bits का, long 64 bits का, arithmetic 2's complement है, और floating-point IEEE floating-point है
    इन चीज़ों को abstract करने की कोशिश में आखिरकार गलत साबित होने पर खर्च होने वाला बहुत सारा समय बचा, और लाखों लोगों ने राहत की सांस ली। character set भी EBCDIC या RADIX-50 नहीं, बल्कि Unicode था

    • Zig और बेहतर है: u8/i8, u16/i16, u32/i32, u64/i64 की तरह size explicit होता है, और arithmetic भी explicitly चुनी जाती है
      + में overflow गलत behavior है, इसलिए debug और releasesafe में abort होता है; +% 2's complement wrapping है, +| saturating arithmetic है। @addWithOverflow() original type और u1 का tuple देता है, और std.math.add() overflow पर error लौटाता है। f16, f32, f64, f80, f128 भी respectively उसी bit length के IEEE floating-point types हैं। byte length कितनी है, यह मायने नहीं रखता; अगर 12-bit byte machine हो तो u12 और i12 इस्तेमाल कर लें
    • यह कहना कि D ने बड़ी छलांग लगाई, अतिशयोक्ति है। explicit size वाले नाम, जैसे u8, i32, हर तरह से काफी बेहतर हैं
    • अगर “byte 8 bits का है”, तो bit कितना बड़ा है?
    • D language के author Bright साहब का खुद ऐसा कहना थोड़ा अपनी ही तारीफ़ नहीं लगता? :)
    • Java ने भी इस मामले में सही किया। unsigned को गलत तरीके से handle किया, लेकिन primitive type bit counts को standardize करने का काम सही किया
      byte = 8 bits, short = 16, int = 32, long = 64, float = 32 bit IEEE, double = 64 bit IEEE
  • कुछ लोगों को अब भी DSP से निपटना पड़ता है: https://thephd.dev/conformance-should-mean-something-fputc-and-freestanding#we-cannot-program-on--vibes-
    निजी तौर पर, मैं मज़ाक में एक unimplemented 12-bit fantasy console document कर रहा हूं, जिसका दावा है “competitors की तुलना में per byte 50% ज्यादा bits!”, और उसमें “UTF-12” जैसी inventions भी डाल रखी हैं

    • मैं यह पता लगाने की कोशिश कर रहा हूं कि अभी कौन-से targets relevant हैं, और क्या वे modern C++ को target करते हैं या करने की योजना रखते हैं
      कई सालों से पूछ रहा हूं, लेकिन कोई positive जवाब नहीं मिला; जिनका ज़िक्र आया उनमें बस TI जैसा कुछ था, इसलिए updated draft में जानकारी जोड़ दी: https://isocpp.org/files/papers/D3477R1.html
    • मुझे लगता है कि बस C++23 या उससे नीचे को target कर लेना चाहिए। मेरे पास कुछ SHARC हैं, लेकिन अगर committee C++30 जैसे किसी version में CHAR_BIT=32 support हटा दे, तो मैं रो-धोकर विरोध नहीं करूंगा
    • क्या PDP-8 12-bit byte इस्तेमाल नहीं करता था?
  • सोच रहा हूँ कि क्या C++ कभी कुछ हटा या सरल कर सकता है
    यह ईमानदार सवाल है और मैंने बहुत बारीकी से follow नहीं किया है। सुना है कि rand() टूटा हुआ है और उसे ठीक नहीं किया जा सकता, लेकिन आख़िरी बार जहाँ तक पता था, वह अभी deprecated होने वाला भी नहीं था। यह प्रस्ताव ऐसा test लगता है कि “क्या हम सचमुच ऐसी समस्या के solution का support भी हटा सकते हैं जिसका सामना शाब्दिक रूप से कोई नहीं करता?”

    • signed integers के लिए 2's complement होना ज़रूरी नहीं था; sign-magnitude, 1's complement, और 2's complement — तीनों representations valid थे
      आधुनिक C और C++ ने इसे छोड़कर 2's complement की मांग कर दी है। यहाँ “as if” वाला अंतर भी practically महत्वपूर्ण नहीं है, और इसे CHAR_BIT पर भी उसी तरह लागू किया जा सकता है, इसलिए ऐसी change का precedent साफ़ तौर पर मौजूद है
    • trigraphs पहले ही हटाए जा चुके हैं, और rand को भी deprecation के लिए चिह्नित किया गया है, साथ में alternative भी दिया गया है
      इसके अलावा p2809 Trivial infinite loops are not Undefined Behavior, p1152 Deprecating volatile, p0907 Signed Integers are Two's Complement, p2723 Zero-initialize objects of automatic storage duration, p2186 Removing Garbage Collection Support भी हैं। इसलिए बदलाव करना संभव है
    • C++11 की GC API C++23 में हटा दी गई, और यह समझ में आता है क्योंकि इसे GC support करने वाली प्रमुख variants, Unreal C++ और C++/CLI, की ज़रूरतों को ध्यान में रखकर design नहीं किया गया था
      exception specifications भी हटाए गए, हालांकि कुछ लोग value-type exceptions के लिए उन्हें वापस लाना चाहते हैं। auto_ptr भी खराब design के कारण हटाया गया। हालांकि simplification के लिहाज़ से बहुत सुधार नहीं हुआ, क्योंकि पुराना तरीका अब भी जानना पड़ता है
    • यह ऐसा व्यंग्य लगता है कि perfection को तोड़ना नहीं है, बल्कि और ज्यादा perfection जमा करनी है
      बात कुछ ऐसी है कि compatibility तोड़े बिना 8-bit byte को भरोसेमंद तरीके से दर्शाने वाला नया C++ symbol चाहिए। जैसे unsigned byte8, 2's complement signed byte8, और ऐसा byte8 जिसका signed behavior defined न हो। accountants के लिए value range 0~10, -10~+10 तक सीमित करने वाले unsigned decimal byte8 और signed decimal byte8, byte की cost तक गिनने वाले accountants के लिए 0~100, -100~+100 वाले centimal byte8, database के age field के लिए मोटे तौर पर पर्याप्त type, और ज़ाहिर है float byte8 भी जोड़ दें — यही मज़ाक है
    • समझ नहीं आता rand() टूटा हुआ क्यों है। वह random जैसे दिखने वाले values बनाता है, और उसका मकसद यही है
      यह cryptographically secure random numbers नहीं बनाता, यह तो स्वाभाविक है, और दूसरी languages के equivalent functions भी ऐसे ही हैं। जल्दी calculate होने वाले, ठीक-ठाक random integers चाहिए हों तो rand() काफी अच्छी तरह काम करता है
  • प्रस्ताव में दिलचस्पी लेने के लिए धन्यवाद, और अब तक मिले feedback के आधार पर updated draft बनाया है: https://isocpp.org/files/papers/D3477R1.html

    • प्रस्ताव की तंज़भरी writing style अच्छी लगी
      खासकर यह वाक्य impressive है: “समस्या यह नहीं है कि क्या ऐसे architectures अब भी मौजूद हैं जहाँ byte 8-bit नहीं है। मौजूद हैं! समस्या यह है कि क्या वे modern C++ की परवाह करते हैं, और क्या modern C++ उनकी परवाह करता है”
  • इस प्रस्ताव को लेकर mixed feelings हैं। एक तरफ़ यह साफ़ तौर पर सही है, और CHAR_BIT का 8 न होना meaningful use cases में काम का नहीं है
    दूसरी तरफ़ ऐसा भी लगता है कि यह इस न्यायपूर्ण world-view के आगे झुकना है कि computer internals के बारे में अपने व्यक्तिगत और बहुत ज़्यादा simplified model से ही दुनिया समझ में आने और reason करने लायक होनी चाहिए। यह approach काफी दूर तक ले जाती है, लेकिन आखिर में dead end है, और अंत में यह मानना पड़ता है कि हम कुछ नहीं जानते, और सही program बनाया है इसका सबसे अच्छा formal argument यही है कि documentation सही होने की शर्त पर वह सही है। यह बड़ा intellectual leap है, और निजी तौर पर, जितना लंबे समय तक मुझे इसे मानने के लिए मजबूर नहीं किया गया, बाद में इसे पार करना उतना कठिन हुआ। फिर भी लगता है कि आजकल beginners में physical electronics projects popular हो रहे हैं, इसलिए उम्मीद है कि “documentation पढ़ो” की जगह “कमबख्त datasheet पढ़ो” नया standard बने

    • फिर भी हर बार autoconf script चलाते समय byte में bits की संख्या check करके उसे config.h में save करते देखता हूँ। जैसे कोई सचमुच उस value के आधार पर कुछ करने की योजना बना रहा हो
    • widely used language हो तो आखिरकार COBOL problem से टकराना पड़ता है। ज्यादातर cases में सब ठीक रहेगा, लेकिन किसी ऐसे system में जहाँ update forced हो, अचानक traffic-control system रुक सकता है या plane crash हो सकता है
      compile process में पूरे पुराने code को check करके यह पता लगाने का तरीका चाहिए कि यह macro पहले से इस्तेमाल हो रहा है या नहीं। ऐसे breaking changes language को split करने का risk भी रखते हैं। यह भी साफ़ नहीं है कि existing codebase CHAR_BIT macro इस्तेमाल करता है या नहीं, और उसे नए compiler पर update किया जा सकता है या नहीं, यह test करना कितना कठिन होगा। कौन-सी library टूटने वाली मानी जाएगी, CHAR_BIT का इस्तेमाल करके compile किए गए दूसरे code के साथ interact करने पर भी problem होगी या नहीं — ऐसे सवाल भी उठते हैं। मैं मानता हूँ कि यह intuition के खिलाफ़ है, लेकिन पहले conversion tool बनाकर यह दिखाना बेहतर होगा कि extreme cases में भी safe है, फिर transition किया जाए
  • यह proposal विवाद-रहित होते हुए भी बेहद तीखा है, इसलिए पसंद आया

  • int8_t == char == 8 bits enforce करना पूरी तरह ठीक है, लेकिन byte 8-bit होता है वाली गलतफहमी फैलाने को लेकर भरोसा नहीं है
    8-bit byte को octet कहते हैं। साथ ही C++17 से byte पहले से ही char का “alias” जैसा भी है: https://en.cppreference.com/w/cpp/types/byte

    • computer से पहली बार परिचय 45 साल पहले हुआ था, और तब भी “byte” को 8-bit quantity के रूप में define किया गया था
      उसके बाद 45 साल में “byte” को किसी और अर्थ में इस्तेमाल होते नहीं देखा, इसलिए अगर 8-bit नहीं वाले “byte” की कोई definition है तो source चाहिए
    • networking RFCs शुरुआत से ही octet शब्द का इस्तेमाल करते आए हैं
    • नहीं, byte 8-bit ही होता है
      यह descriptive statement नहीं, बल्कि normative statement है
    • व्यक्तिगत रूप से मुझे int8 == signed char पसंद नहीं है
      std::cout << (int8_t)32 << std::endl; को स्वाभाविक रूप से 32 print करना चाहिए
  • C++ से सीधे जुड़ा नहीं है, लेकिन 6-bit byte वाले रेट्रो microcomputer का आइडिया मुझे काफी पसंद है। जैसे 24-bit को word माना जाए
    Microcomputer आम तौर पर कम संख्या में objects से काम करते हैं और pointers की तुलना में arrays को प्राथमिकता देते हैं, इसलिए memory बचाई जा सकती है। VGA में प्रति color 6 bits थे, 6x4 bit matrix से पढ़ने लायक alphabet बनाया जा सकता है, basic LISP या Forth भाषाओं को भी 6-bit alphabet में फिट किया जा सकता है, और मूल System/360 केवल 24-bit addresses इस्तेमाल करता था। स्वतंत्र रूप से address किए जा सकने वाले 6-bit units की 12MiB memory किसी के लिए भी काफी होनी चाहिए। अगर कम पड़े, तो FAT-12 को स्वाभाविक रूप से FAT-24 तक बढ़ा दें, या 64-bit pointers जितने ही उपयोगी 48-bit pointers इस्तेमाल करें

    • या फिर 8-bit byte और 3-byte word इस्तेमाल कर लें। तब भी 24-bit ही रहेगा