जहां तक मुझे पता है, संदर्भ / पॉइंटर एलियासिंग कंपाइलर की क्षमता को अनुकूलित कोड उत्पन्न करने में बाधा डाल सकते हैं, क्योंकि उन्हें यह सुनिश्चित करना चाहिए कि उत्पन्न बाइनरी सही तरीके से उस मामले में व्यवहार करती है जहां दो संदर्भ / पॉइंटर्स वास्तव में उपनाम हैं। उदाहरण के लिए, निम्नलिखित C कोड में,
void adds(int *a, int *b) {
*a += *b;
*a += *b;
}
जब ध्वज के clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
साथ संकलित किया जाता है -O3
, तो यह निकलता है
0000000000000000 <adds>:
0: 8b 07 mov (%rdi),%eax
2: 03 06 add (%rsi),%eax
4: 89 07 mov %eax,(%rdi) # The first time
6: 03 06 add (%rsi),%eax
8: 89 07 mov %eax,(%rdi) # The second time
a: c3 retq
यहां कोड (%rdi)
दो बार केस int *a
और int *b
उर्फ में वापस स्टोर होता है ।
जब हम संकलक को स्पष्ट रूप से बताएंगे कि ये दोनों संकेत restrict
कीवर्ड के साथ नहीं जा सकते हैं :
void adds(int * restrict a, int * restrict b) {
*a += *b;
*a += *b;
}
फिर क्लैंग बाइनरी कोड के अधिक अनुकूलित संस्करण का उत्सर्जन करेगा:
0000000000000000 <adds>:
0: 8b 06 mov (%rsi),%eax
2: 01 c0 add %eax,%eax
4: 01 07 add %eax,(%rdi)
6: c3 retq
चूँकि Rust सुनिश्चित करता है (असुरक्षित कोड को छोड़कर) कि दो परस्पर संदर्भ अलग नहीं हो सकते, मुझे लगता है कि संकलक को कोड के अधिक अनुकूलित संस्करण का उत्सर्जन करने में सक्षम होना चाहिए।
जब मैं नीचे दिए गए कोड के साथ परीक्षण करने और साथ यह संकलन rustc 1.35.0
के साथ -C opt-level=3 --emit obj
,
#![crate_type = "staticlib"]
#[no_mangle]
fn adds(a: &mut i32, b: &mut i32) {
*a += *b;
*a += *b;
}
यह उत्पन्न करता है:
0000000000000000 <adds>:
0: 8b 07 mov (%rdi),%eax
2: 03 06 add (%rsi),%eax
4: 89 07 mov %eax,(%rdi)
6: 03 06 add (%rsi),%eax
8: 89 07 mov %eax,(%rdi)
a: c3 retq
यह उस गारंटी का लाभ नहीं उठाता जो a
और b
अन्य नहीं हो सकती।
क्या यह इसलिए है क्योंकि वर्तमान जंग संकलक अभी भी विकास में है और अभी तक अनुकूलन करने के लिए उर्फ विश्लेषण को शामिल नहीं किया है?
क्या ऐसा इसलिए है क्योंकि सुरक्षित रुस्तम में भी अभी भी एक मौका है a
और b
वह अन्य लोगों को भी दे सकता है?
unsafe
कोड में भी , परिवर्तनशील संदर्भों की अनुमति नहीं है और अपरिभाषित व्यवहार का परिणाम होता है। आपके पास कच्चे पॉइंटर्स अलियासिंग हो सकते हैं, लेकिन unsafe
कोड आपको वास्तव में रस्ट मानक नियमों की अनदेखी करने की अनुमति नहीं देता है। यह सिर्फ एक आम गलत धारणा है और इस तरह इशारा करने लायक है।
+=
शरीर में दो ऑपरेशनों की adds
फिर से व्याख्या की जा सकती है *a = *a + *b + *b
। यदि संकेत अन्य नहीं हैं, तो वे कर सकते हैं, आप यह भी देख सकते हैं कि b* + *b
दूसरी एएसएम सूची में क्या मात्राएँ हैं 2: 01 c0 add %eax,%eax
:। लेकिन अगर वे उर्फ करते हैं, तो वे नहीं कर सकते, क्योंकि जब तक आप *b
दूसरी बार जोड़ते हैं , तब तक इसमें पहली बार के आस-पास (आप 4:
पहले asm लिस्टिंग की लाइन पर स्टोर करने वाले) की तुलना में एक अलग मूल्य होगा ।