- क्रिप्टोग्राफिक कोड में महत्वपूर्ण constant-time गुण सिर्फ compiler optimization से भी टूट सकता है, इसलिए LLVM के अंदर warning patch डालकर जोखिमपूर्ण patterns खोजने का प्रयोग किया जा रहा है
- compiler “optimization” कुछ benchmarks को तेज़ बना सकती है, लेकिन असली hot path अक्सर intrinsics और assembly पर निर्भर करते हैं, और optimization से पैदा हुए bugs की लागत अलग से जुड़ती रहती है
- जून 2024 में Antoon Purnal ने पुष्टि की कि Kyber reference code, Clang 15 या उसके बाद के कुछ optimization options में secret value पर आधारित conditional branch में बदल सकता है, जिससे timing attack संभव हो सकता है
- TIMECOP 2, SUPERCOP के अंदर constant-time घोषित compiled results की जांच करता है, लेकिन Valgrind-supported instructions और वास्तविक test execution में दिखने वाले data flow तक इसकी सीमाएँ हैं
- व्यावहारिक जवाब यह है कि
crypto_{int,uint}{8,16,32,64}.h जैसी functions का उपयोग कर compiler को 1-bit result को bool की तरह देखने से रोका जाए, या verified assembly, security-oriented languages, और dedicated compilers की ओर जाया जाए
compiler “optimization” से बनता ज़िम्मेदारी का खालीपन
- हाल के LLVM और GCC change logs में “optimization”, “optimization” tests, test fixes, और “optimization” bug fixes लगातार दिखाई देते हैं
- compile होने से पहले सही चलने वाला code, compiler change के बाद बदल जाए, तब भी कई मामलों में ज़िम्मेदारी उस programmer पर डाल दी जाती है जिसने “undefined behavior” को छुआ हो
- ऐसे “language standards” compiler writers बनाते हैं, और नतीजतन लाखों programmers का code, compiler writers के छोटे समूह के बदलावों से पैदा हुई ज़िम्मेदारी ढोता है
- क्रिप्टोग्राफिक code के उदाहरण में, कई CPU benchmarks पर
kyber768 का avx2 implementation, “optimized” compiler से compile किए गए portable code से लगभग 4 गुना तेज़ है
optimization performance measurement की सीमाएँ
- 2000 में Todd A. Proebsting ने Proebsting's Law में कहा कि “compiler advances हर 18 साल में computing power को दोगुना करती हैं”, और निष्कर्ष निकाला कि compiler optimization का योगदान सीमांत है
- Arseny Kapoulkine ने 2022 के benchmark में संक्षेप में बताया कि LLVM 11, LLVM 2.7 की तुलना में optimized compilation में 2 गुना अधिक समय लेता है, जबकि generated code आम तौर पर 10~20% तेज़ होता है
- दोनों चर्चाएँ उस performance measurement को छोड़ देती हैं जिसे असली user महसूस करता है
- performance-केंद्रित hotspots में intrinsics और assembly बहुत इस्तेमाल होते हैं
- FFmpeg में
.asm और .S files मिलाकर 160,000 lines assembly हैं
- जैसे-जैसे computers और networks अधिक data संभालते हैं, वास्तविक CPU time ऐसे hotspots पर और अधिक केंद्रित होता जाता है
- security cost भी optimization चर्चा के बाहर अलग से बढ़ती है
- Deloitte ने बताया कि 2023 में IT security budget, corporate revenue का 0.5% था
- 2022 में वैश्विक corporate total revenue 48 trillion dollars से अधिक होने के आँकड़े के साथ देखें, तो कुल पैमाना सैकड़ों अरब dollars का हो सकता है
- हालाँकि यह भी ध्यान देने योग्य है कि Deloitte का 0.5% शायद company-wise simple average हो, और सभी कंपनियों ने survey का जवाब नहीं दिया था
timing leak और Kyber मामला
- “optimized” compilers से बनने वाली security problems में सिर्फ पारंपरिक bugs ही नहीं, बल्कि timing leak भी शामिल है, जहाँ secret information execution time में रिसती है
- Laurent Simon, David Chisnall, Ross Anderson का EuroS&P 2018 paper चेतावनी देता है कि compiler upgrade बिना चेतावनी के पहले से सुरक्षित code में timing channel खोल सकता है
- 2018 paper में ज़ोर दिया गया उदाहरण वह code था जो
bool से दो values में से एक चुनता था, और bool compiler को conditional jump बनाने के लिए प्रेरित करता था
- cryptographic implementations में इससे बचने के लिए महत्वपूर्ण code से
bool हटाया जाता है और अलग constant-time comparison functions बनाई जाती हैं
- उद्धृत किया गया है कि OpenSSL इसके लिए 37 functions घोषित करता है
- 2015 का
curve25519-donna और MSVC 2015 मामला लेख में गलतफहमी के रूप में व्यवस्थित किया गया है
- वास्तव में 32-bit x86 के लिए compile करते समय
int64 operations, Microsoft की 32-bit int64 library llmul.asm call में बदल जाती थीं
- timing leak,
llmul.asm की data-dependent branch से पैदा हुई, और इस library को भी उचित source-code अवधारणा का हिस्सा माना जाना चाहिए
- जून 2024 में Antoon Purnal ने पुष्टि की कि Kyber reference code, Clang 15 या उसके बाद के कुछ optimization options में timing attack की अनुमति दे सकता है
- समस्या का रूप
(-((x>>j)&1))&y था, जो x का j-वाँ bit set होने पर y, अन्यथा 0 बनाता है
- Clang, bit-test instruction से उस bit को
bool में बदलता है, और फिर उस bool के आधार पर conditional branch बनाता है
- LLVM के अंदर
lib/CodeGen/SelectionDAG/DAGCombiner.cpp का combineShiftAnd1ToBitTest यह “optimization” संभालता है
- यह function Sanjay Patel ने सितंबर 2019 में जोड़ा था, और बाद में कई लोगों ने इसमें बदलाव किए
- GCC में भी सीमा लाँघने जैसा एक समान मामला है
- ARM के नवंबर 2021 के GCC patch ने
(-x)>>31 को -(x>0) में बदला
- अप्रैल 2024 में इस पर चेतावनी जारी हुई
TIMECOP और constant-time जांच
- TIMECOP 2, SUPERCOP cryptographic test framework में built-in है, और constant-time घोषित compiled code में secret-value-derived conditional branches की स्वचालित जांच करता है
- जांच का दायरा conditional branches के अलावा secret values से निकले array indexes को भी शामिल करता है
- KyberSlash paper secret-value-derived division की जांच के लिए patch का भी वर्णन करता है
- TIMECOP 1, Moritz Neikes द्वारा SUPERCOP में बदलाव कर बनाया गया tool था, जिसने Adam Langley के ctgrind approach को automate किया
- TIMECOP 2 ने पुराने approach पर कुछ विस्तार किए
- RNG output को अपने आप secret values के रूप में mark करता है
- “declassification” को support करता है
- “public inputs” designation को support करता है
- कई cores पर चलता है
- TIMECOP की स्पष्ट सीमाएँ हैं
- यह सिर्फ Valgrind द्वारा supported instructions को संभाल सकता है, इसलिए AMD XOP instructions जैसी चीज़ों पर रुक जाता है
- यह सिर्फ वही data flow जांचता है जो वास्तविक test execution में दिखाई देता है
- constant-time behavior की जांच के tools पर काम जारी है, और संबंधित tools की सूची ct-tools पर है
- TIMECOP जैसी जांच libmceliece test suite में शामिल की गई है, और यह अन्य libraries तक भी फैल सकती है
constant-time rewrite तरीका
- variable-time code fragments खोज लेने के बाद, उन्हें bug के बिना constant-time में दोबारा लिखने का तरीका चाहिए
- जुलाई 2024 की प्रस्तुति में libmceliece और SUPERCOP द्वारा दिए गए कुछ constant-time functions का परिचय कराया गया
- file names हैं
crypto_{int,uint}{8,16,32,64}.h
- इन files को दूसरे projects में copy करके इस्तेमाल किया जा सकता है
- उदाहरण function
crypto_uint32_bitmod_mask(x,j) का effect -((x>>(j&31))&1) जैसा है, लेकिन compiler को 1-bit result देखने से रोकता है
- अधिक जटिल उदाहरण के रूप में
crypto_uint32_max(x,y) भी है
- 2018 paper में Clang/LLVM में constant-time function
__builtin_ct_choose(bool cond, x, y) जोड़ने वाले tweak की चर्चा है
- paper ने गलत तरीके से सुझाव दिया कि सिर्फ यह एक function काफी होगा
- यह function कभी compiler में आ सकता है, लेकिन किसी project के लिए उस पर निर्भर करना संभव होने में बहुत समय लग सकता है
- इसके implementation approach को
crypto_{int,uint}{8,16,32,64}.h से अधिक नाज़ुक माना गया है
समस्या को पहले से टालने के तरीके
- यदि compiled library की pre-distribution testing, compiler-introduced timing leaks पकड़ ले, तो code rewrite के दौरान deployment में पुराना compiler version इस्तेमाल किया जा सकता है
- यह users को सुरक्षित रखने वाला एक अस्थायी जवाब है
- एक समाधान library को assembly में distribute करना है
- RWC 2024 की प्रस्तुति Adoption of high-assurance and highly performant cryptographic algorithms at AWS तेज़ X25519 software दिखाती है, जिसके बारे में प्रमाणित है कि वह सभी inputs पर X25519 को सही तरह compute करता है
- implementation, 64-bit Intel/AMD CPU के लिए 2 versions और 64-bit ARM CPU के लिए 2 versions वाली assembly में लिखा गया है
- correctness statement उस machine code के बारे में है जिसे user वास्तव में चलाता है, और proof को HOL Light theorem prover से verify किया गया है
- लेकिन जो cryptographic software अभी उस स्तर तक नहीं पहुँचा है, उसमें assembly की auditing difficulty अब भी बनी रहती है
- C, C++ आदि में लिखे code में timing leaks रोकने वाली “vaccine” जल्दी डालने के तरीकों की भी खोज हो रही है
clang-vs-clang patch प्रयोग
x&1 और x>>31 में एक समानता है: इनके परिणाम की सिर्फ दो संभावनाएँ होती हैं
x&1 है 0 या 1
uint32 का x>>31 है 0 या 1
int32 का x>>31 है 0 या -1
- ऐसी shapes compiler “optimization” लिखने वालों के लिए 1-bit result को
bool में डालना आसान बना देती हैं
- यह सिफारिश की गई है कि हमेशा
-fwrapv के साथ compile करें ताकि GCC और Clang, two's-complement arithmetic मानें
- सिर्फ source में
&1, 1&, >>31 आदि scan करने पर भी कई examples मिल जाते हैं, लेकिन यहाँ LLVM “optimizer” में सीधे patch डालकर दूसरे तरीके से scan किया गया
- patch LLVM commit
68df06a0b2998765cb0a41353fcf0919bbf57ddb से शुरू होती है, &1 और >>31 खोजती है, और यह warning देती है
please take this away before clang does something bad
- उदाहरण compile command है
clang -Rpass-analysis=clang-vs-clang -O -c x.c
- test function इस प्रकार है
int sra31(int x)
{
x >>= 31;
return x;
}
- वही warning बार-बार दिखना आश्चर्यजनक नहीं है
- compiler “optimization” तब तक बार-बार लागू करने की कोशिश करता है जब तक आगे कोई प्रगति संभव न रहे
clang-vs-clang output, shift में signed और unsigned का फर्क दिखाती है
- यह फर्क
crypto_{int,uint}{8,16,32,64}.h आधारित manual या automatic rewrite में महत्वपूर्ण है
- source transformation automate करने के तरीकों में
clang-tidy एक उदाहरण है
- जो code
#ifdef से हट चुका हो या इस “optimization” stage से पहले eliminate हो गया हो, वह clang-vs-clang warning नहीं बनाता
SUPERCOP run results और खोजे गए मामले
- SUPERCOP 20240716 को dual EPYC 7742 पर
./data-do-biglittle से चलाया गया
- overclocking disable थी
- SUPERCOP compiler list में
okcompilers/{c,cpp} की clang line में -Rpass-analysis=clang-vs-clang जोड़कर clang-vs-clang इस्तेमाल करने के लिए समायोजन किया गया
- results 3 घंटे बाद तैयार हुए
- Clang output कुल 675,752 lines था
- raw size 210,786,494 bytes थी
- compressed result 3,595,199 bytes का
20240803-fromclang.txt.gz है
- output में public data आधारित source branches से, Clang के अंदर
&1 बनने की वजह से बहुत noise है
- साफ़ तौर पर पहले से बदल देने लायक उदाहरण यह है
a0 += (a0>>15)&106;
- ऐसा उदाहरण जिसे साधारण source scan से पकड़ने के लिए C parsing effort चाहिए, यह है
- macro
ONE8 को ((uint8_t)1) के रूप में define किया गया है
*pk2^=(((* pk_cp)>>ir)&ONE8)<<jr;
- और कठिन उदाहरण AVX2 intrinsic-आधारित macro से आता है
signmask_x16(x) को _mm256_srai_epi16((x),15) के रूप में define किया गया है
- यह 256-bit vector के भीतर हर signed 16-bit chunk को 15 bits right shift करता है
mask = signmask_x16(sub_x16(x,const_x16((q+1)/2)));
- यह AVX2 मामला फिलहाल उच्च प्राथमिकता का नहीं है
- vector operation को conditional branch में बदलने के लिए AVX-512 से compile करना होगा, और compiler को vectorized
bool को serial bool conditional branches में बदलने जैसा अजीब फैसला लेना होगा
- TIMECOP, Valgrind का उपयोग करता है, और Valgrind AVX-512 को support नहीं करता
- अभी के लिए AVX-512 compilation की सिफारिश नहीं की जाती
int128 और व्यापक प्रतिक्रिया की दिशा
- सबसे रोचक खोज वह मामला था जहाँ
int128 का 64-bit right shift, >> warning पैदा कर रहा था
int128 implementation अंदरूनी तौर पर upper 64-bit word का sign जानने के लिए 63-bit right shift का उपयोग कर सकता है
- अगर Clang, GCC की तरह 63-bit right shift को
bool और फिर conditional branch में बदलने का support जोड़ दे, तो बहुत सा int128 code अचानक variable-time बन सकता है
- इस स्थिति में 2015 paper के title में दावा किया गया परिदृश्य जैसा कुछ होगा, लेकिन इस बार source में
bool न होते हुए भी
- source level पर सबसे आसान सुरक्षा यह है कि compiler के मौजूदा
int128 implementation से बचा जाए और crypto_int128 functions इस्तेमाल किए जाएँ
crypto_int128, GCC और Clang के int128 से अलग, छोटे 32-bit platforms पर भी काम कर सकता है
- GCC और Clang में secret data types जोड़ने का विचार अच्छा लगता है, लेकिन दोनों compilers की संरचना में इसे मज़बूती से बनाने का रास्ता स्पष्ट नहीं दिखता
- उम्मीद उन compilers से अधिक है जिन्हें शुरू से security के लिए design किया गया है
- नए input language की माँग करने वाले security-focused compilers में FaCT और सक्रिय रूप से विकसित हो रहा Jasmin शामिल हैं
- code rewrite समय को लेकर चिंता है, लेकिन मौजूदा compilers जिस तरह existing code को संभालते हैं, उसे देखते हुए किसी न किसी रूप में कार्रवाई ज़रूरी लगती है
1 टिप्पणियां
Hacker News पर टिप्पणियां
जिस code ने undefined behavior किया हो, उसके मनचाहे तरीके से न चलने को compiler bug कहना सही नहीं है
यह कुछ वैसा ही है जैसे गलत arguments के साथ
ddचलाकर data उड़ा देना और फिर कहना किddमें bug हैsource code या compiler को bug कहना मुश्किल है; कहना बेहतर होगा कि C standard, लेखक के मानकों के हिसाब से, बहुत कम specified है और कुछ targets पर security bugs पैदा कर देता है
आखिर C standard के लेखक hardware के behavior तक define नहीं कर सकते, वे सिर्फ language semantics define कर सकते हैं, इसलिए crypto वालों को hardware की वजह से होने वाले bugs से जूझना ही पड़ता है
Rust के फायदों में से एक यह है कि वह संभावित undefined behavior को
unsafeblocks के अंदर सीमित कर देता है। फिर भी, C में जो कई चीजें undefined behavior हैं उन्हें Rust ने define कर रखा है, लेकिनunsafecode में जाते ही सूक्ष्म undefined behavior पर गलती से पैर रख देना बहुत आसान हैतीसरा model, जिसमें चुपचाप fail होकर unpredictable code generate होता है, सिर्फ compiler authors के लिए उपयोगी है। spec के पीछे छिपना असली users के लिए फायदेमंद नहीं है
वह optimization उस code को तोड़ देती है जो पहले ठीक से चलता था। compiler authors backward compatibility को प्राथमिकता दे सकते थे, लेकिन वे ऐसा नहीं करते
ऊपर से ऐसी optimizations वास्तविक code performance को meaningful तरीके से सुधारती भी नहीं हैं, इसलिए code तोड़ने वाले trade-off की कीमत नहीं है—इस दावे का जवाब देना होगा
Bernstein मुझे पसंद हैं, लेकिन कभी-कभी वे गलत दिशा पकड़कर उग्र हो जाते हैं, और यह लेख उसका अच्छा उदाहरण है। लेख के अंत में वे खुद भी आधा-सा मानते हैं
लेख का बड़ा हिस्सा इस secondary point पर है कि optimization gains कितने अच्छे हैं, और data होने पर भी यह use case के हिसाब से बदलने वाला judgement है
मुख्य शिकायत यह है कि C compiler उन semantics को consider नहीं करता जिन्हें भाषा में express नहीं किया जा सकता, और यह कोई हैरानी की बात नहीं है
अंत में वे कहते हैं, “ऐसी भाषा इस्तेमाल करें जो जरूरी semantics express कर सके”; पूरा लेख उसी एक वाक्य से बदला जा सकता था
उनमें से काफी का आधार संदिग्ध है, और वे सही program लिखना और कठिन बना देते हैं
C और C++ constant-time guarantees वाले algorithms लिखने के लिए उपयुक्त नहीं हैं
standard में real-time की अवधारणा लगभग नहीं है, और compiler भी extensions के रूप में अतिरिक्त guarantees नहीं देते
लेकिन इसका दोष compiler developers पर डालना गलत दिशा है
Intel CPU पर
clangहो या कुछ और, user mode में सही code generate नहीं कर सकता। क्योंकि शुरुआत से ही कोई सही code मौजूद नहीं हैhttps://www.intel.com/content/www/us/en/developer/articles/t...
document में
DOITMदेखें—user-space crypto library के लिए जरूरी bit set करना simply impossible हैएक बार on हो जाए तो user space में भी ठीक चलता है, इसलिए जैसे
prctlsystem call से enable होने वाला per-process flag हो सकता है, और scheduler task switch के समयMSRadjust कर सकता हैसिर्फ़ यह वाक्य देखकर ही—“जब भी संभव हो, compiler लिखने वाले अपने बनाए bugs की ज़िम्मेदारी लेने से इनकार करते हैं”—ब्लॉग पोस्ट की विशेषज्ञता इतनी जल्दी ढहते देखना दुर्लभ है
अगर link तक जाकर देखें, तो यह बस C की बेहद बुनियादी बात है कि undefined behavior का मतलब “कोई भी arbitrary value” बनना नहीं होता
undefined behavior होने पर भी source code bug हो सकता है, लेकिन generated program फिर भी अक्सर सही हो सकता है। बाद में जब compiler लेखक नया optimization डालकर उसी undefined behavior के आधार पर bug वाला program generate करता है, तब ज़िम्मेदारी को लेकर बहस शुरू होती है
जिस हिस्से को लोग मानना नहीं चाहते, वह यह है कि users के प्रति ज़िम्मेदारी सभी पक्षों में बंटी होती है। अगर किसी CRUD app ने
NULLdereference किया और सिर्फ़ इसी वजह से battery जल गई, तो कोई सामान्य इंसान सिर्फ़ app लेखक कोNULLcheck भूलने के लिए दोषी नहीं ठहराएगाCompiler, operating system और hardware कंपनियों को भी अपने गैर-ज़िम्मेदाराना ढंग से design किए गए products की ज़िम्मेदारी लेनी चाहिए; ISO standard में “undefined behavior” कह देने भर से बात खत्म नहीं हो जाती। supply chain के सभी सदस्य यह अनुमान लगाने और उचित रूप से संभालने की साझा ज़िम्मेदारी रखते हैं कि product का दुरुपयोग कैसे हो सकता है
undefined behavior value देने के लिए मौजूद होता है। उसके बिना भी भाषा बनाई जा सकती है, लेकिन उसे रखने की वजह portability और compiler लेखकों को मिलने वाली flexibility है
लेख का मुख्य सवाल यह है कि क्या यह flexibility, undefined behavior के बिना program लिखने की कठिनाई की तुलना में वाकई मूल्यवान है
लेखक को लगता है कि bugs से खोया पैसा तेज़ bytecode से बचाए गए पैसे से ज़्यादा है, और language standard में क्या जाएगा यह तय करते समय compiler लेखकों का प्रभाव बड़ा होता है, इसलिए इसे सुधारने की इच्छाशक्ति कम है
संदर्भ के लिए,
clangमें हर function के लिए सभी optimizations बंद करने वालाclang::optnoneattribute है, और GCC में नाम से optimizations जोड़ने/हटाने या compiler flags से स्वतंत्र रूप से optimization level तय करने वाला बढ़ियाgnu::optimizeattribute हैgnu::optimize(0)उसclangflag जैसा ही है।clangमें खास तौर परmemcpyऔरmemsetoptimizations बंद करने वालाclang::no_builtinsभी हैoptimizeattribute का उपयोग केवल debugging purposes के लिए किया जाना चाहिए, और यह production code के लिए उपयुक्त नहीं है”https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attribute...
crypto वाले लोग जिन लक्ष्यों को चाहते हैं, जैसे constant-time evaluation और secret values छिपाना, उनसे मैं कुछ हद तक सहमत हूं
लेकिन general-purpose compiler ज़्यादातर समय ऐसी चीज़ों के बारे में नहीं सोचता, इसलिए यह आम तौर पर चल जाने वाले hack से ज़्यादा बनना मुश्किल लगता है
अगर इसे गंभीरता से करना है तो शायद अपना special-purpose compiler चाहिए, या फिर assembly पर ही चलते रहना होगा
शायद कभी हम आज के दौर को पुराने बुरे दिनों की तरह देखेंगे, और C से आगे बढ़कर ऐसी भाषा इस्तेमाल कर रहे होंगे जिसमें undefined behavior कहीं कम होगा
C में ऐसे expressions लिखना बहुत आसान है जो compile तो हो जाते हैं, लेकिन compiler के लिए लेखक की मंशा समझना लगभग नामुमकिन होता है
उदाहरण के लिए Python में
result = [something(value) for value in set_object]जैसा code लिखा जा सकता है।setobject unordered होता है, इसलिए यह साफ है कि items को process करने का क्रम और result का क्रम महत्वपूर्ण नहीं है, और इससे compiler को लेखक की मंशा का अनुमान लगाए बिना language level पर कई optimizations के रास्ते खुलते हैंimmutable data वाली दूसरी languages में similar code एक कदम और आगे जाता है:
something(value1)something(value2)को प्रभावित नहीं कर सकता, इसलिए उसे threads हों या processes, parallel में चलाया जा सकता हैC compiler optimization का बड़ा हिस्सा code patterns देखकर यह पता लगाने की कोशिश है कि लेखक शायद क्या करना चाहता था और उसे तेज़ कैसे किया जाए। Modern languages की तुलना में C में intent व्यक्त करने की क्षमता कम है, इसलिए अनुमान लगाने की आज़ादी तो है, लेकिन decent performance पाने के लिए ऐसा inference करना पड़ता है
फिर भी यह Hubble telescope को चश्मे की जरूरत पड़ने वाली घटना की तरह भेष में blessing भी हो सकता है। सीमाओं को पार करने के लिए बेहतरीन techniques बनीं, और समस्या ठीक होने के बाद उन्हीं techniques ने मूल उम्मीद से कहीं ज़्यादा performance दी। C compiler optimizations को non-C languages पर लागू किया जाए तो वे superpower की तरह काम कर सकती हैं
मूल रूप से यह undefined behavior जैसा है, लेकिन तुरंत safety issue के बजाय गलत result के रूप में दिख सकता है। बेशक गलत result आगे चलकर safety issue बन सकता है
undefined behavior के उलट, ऐसा “sanitizer” बनाना व्यावहारिक रूप से असंभव है जो जांचे कि code सभी संभव
setorders में काम करता है या नहींgccऔरclangमें कई low-level hints हैं जो दूसरी languages में अक्सर नहीं मिलते।__builtin_expect/__builtin_unpredictable,__builtin_unreachable/__builtin_assume,#pragma clang loop vectorize(assume_safety)/#pragma GCC ivdep, loop unrolling या vectorization बंद करने या किसी खास value को चुनने वाले pragma आदिमेरे हिसाब से सबसे बड़ी कमी optimization barrier की है, जो स्पष्ट रूप से compiler को किसी value के source के आधार पर inference करने से रोक सके।
__asm__कुछ हद तक यह कर सकता है, लेकिन उसके unwanted side effects हैं और platform-specific register type names की जरूरत पड़ती हैhigh-level intent-based optimization की संभावना भी साफ है। जैसे loop में
nबारpushकरने से पहले array list space reserve करना, same key के साथcontains→get→putकरने वाली hashmap lookup को merge करना, या global allocation behavior को local तौर पर infer करके objects और allocations हटानाC real hardware के पर्याप्त करीब है, इसलिए programmer सीधे बता सकता है कि क्या करना है; compiler को programmer की मंशा का अनुमान लगाने की जरूरत नहीं पड़ती
ऐसी memory optimizations implement करने वाली languages आम तौर पर Java जैसी होती हैं, और उनमें शुरू से ही aggressive upfront pessimization होती है, इसलिए ऐसी optimization करने की प्रेरणा बनती है। लेकिन उन optimizations से भी नुकसान की भरपाई नहीं होती
मुद्दा यह है कि C भी बहुत अच्छा नहीं है, लेकिन दूसरी तरफ हालत और खराब है
अगर C की semantics पसंद नहीं है, तो compiler engineers पर गुस्सा न करें, कोई दूसरी programming language इस्तेमाल करें
qhasmके अलावा कुछ भी बर्दाश्त कर पाएगा या नहीं। Zig भी नहीं। यह review उसकी तरफ से इतना चौंकाने वाला नहीं हैयह एक ताज़ा लेख है जो ऐसा नजरिया देता है जो अक्सर सुनने को नहीं मिलता। साथ में देखने लायक: https://gavinhoward.com/2023/08/the-scourge-of-00ub/