Soweit ich weiß, kann Referenz- / Zeiger-Aliasing die Fähigkeit des Compilers beeinträchtigen, optimierten Code zu generieren, da sie sicherstellen müssen, dass sich die generierte Binärdatei korrekt verhält, wenn die beiden Referenzen / Zeiger tatsächlich Alias sind. Zum Beispiel im folgenden C-Code:
void adds(int *a, int *b) {
*a += *b;
*a += *b;
}
Wenn es clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)mit dem -O3Flag kompiliert wird , wird es ausgegeben
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
Hier speichert der Code (%rdi)zweimal in case int *aund int *balias.
Wenn wir dem Compiler ausdrücklich mitteilen, dass diese beiden Zeiger keinen Alias mit dem restrictSchlüsselwort haben können:
void adds(int * restrict a, int * restrict b) {
*a += *b;
*a += *b;
}
Dann wird Clang eine optimierte Version des Binärcodes ausgeben:
0000000000000000 <adds>:
0: 8b 06 mov (%rsi),%eax
2: 01 c0 add %eax,%eax
4: 01 07 add %eax,(%rdi)
6: c3 retq
Da Rust (außer in unsicherem Code) sicherstellt, dass zwei veränderbare Referenzen keinen Alias haben können, würde ich denken, dass der Compiler in der Lage sein sollte, die optimierte Version des Codes auszugeben.
Als ich mit dem Code testen unten und kompilieren Sie es mit rustc 1.35.0mit -C opt-level=3 --emit obj,
#![crate_type = "staticlib"]
#[no_mangle]
fn adds(a: &mut i32, b: &mut i32) {
*a += *b;
*a += *b;
}
es erzeugt:
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
Dies nutzt die Garantie nicht aus aund bkann nicht alias.
Liegt das daran, dass sich der aktuelle Rust-Compiler noch in der Entwicklung befindet und noch keine Alias-Analyse für die Optimierung integriert hat?
Liegt das daran, dass es immer noch eine Chance gibt aund bAlias auch in sicherem Rust sein könnte?
unsafeAliasing veränderlicher Verweise auch im Code nicht zulässig ist und zu undefiniertem Verhalten führt. Sie können Aliasing-Rohzeiger verwenden, aber mit unsafeCode können Sie die Rust-Standardregeln nicht ignorieren. Es ist nur ein weit verbreitetes Missverständnis und daher erwähnenswert.
+=Operationen im Körper von addsals neu interpretiert werden können *a = *a + *b + *b. Wenn die Zeiger keinen Alias haben, können Sie sogar b* + *bin der zweiten ASM-Liste sehen, was sie bedeuten : 2: 01 c0 add %eax,%eax. Wenn sie jedoch einen Alias verwenden, können sie dies nicht, da er *bzum zweiten Mal einen anderen Wert enthält als beim ersten Mal (den Wert, den Sie online 4:in der ersten ASM-Liste speichern ).