เท่าที่ฉันรู้การอ้างอิงนามแฝงตัวชี้ / สามารถขัดขวางความสามารถของคอมไพเลอร์ในการสร้างรหัสที่ดีที่สุดเพราะพวกเขาจะต้องตรวจสอบให้แน่ใจว่าการสร้างไบนารีทำงานอย่างถูกต้องในกรณีที่ทั้งสองอ้างอิง / พอยน์เตอร์นามแฝงแน่นอน ตัวอย่างเช่นในรหัส 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
เนื่องจากสนิมทำให้แน่ใจ (ยกเว้นในรหัสที่ไม่ปลอดภัย) ว่าการอ้างอิงที่ไม่แน่นอนทั้งสองไม่สามารถใช้นามแฝงได้ฉันจึงคิดว่าคอมไพเลอร์ควรจะปล่อยโค้ดที่ได้รับการปรับให้เหมาะสมที่สุด
เมื่อผมทดสอบด้วยโค้ดด้านล่างและเรียบเรียงด้วย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นามแฝงแม้ใน Rust ที่ปลอดภัยหรือไม่
unsafeรหัสการอ้างอิงนามแฝงที่ไม่แน่นอนไม่ได้รับอนุญาตและทำให้เกิดพฤติกรรมที่ไม่ได้กำหนด คุณสามารถใช้นามแฝงตัวชี้แบบ raw ได้ แต่unsafeรหัสไม่อนุญาตให้คุณละเว้นกฎมาตรฐานของสนิม เป็นเพียงความเข้าใจผิดที่พบบ่อยและคุ้มค่าที่จะชี้ให้เห็น
                +=ปฏิบัติการทั้งสองในร่างกายของaddsสามารถตีความได้ว่าเป็น*a = *a + *b + *bอย่างไร หากตัวชี้ไม่นามแฝงพวกเขาสามารถคุณยังสามารถมองเห็นสิ่งที่จำนวนเงินb* + *bใน asm 2: 01 c0  add  %eax,%eaxสองรายการ: แต่ถ้าพวกเขาทำนามแฝงพวกเขาไม่สามารถทำได้เพราะเมื่อคุณเพิ่ม*bเป็นครั้งที่สองมันจะมีค่าที่แตกต่างจากครั้งแรกที่อยู่รอบ ๆ (อันที่คุณเก็บไว้ใน4:รายการแรกของ asm)