NonZeroU32 :: get이 0을 반환하지 않는다는 것을 옵티 마이저에 알리는 방법은 무엇입니까?
Nov 16 2020
문제가 발생한 코드 샘플은 다음과 같습니다.
pub fn div(x: u32, y: u32) -> u32 {
x / y
}
pub fn safe_div(x: u32, y: std::num::NonZeroU32) -> u32 {
x / y.get() // an unchecked division expected
}
Godbolt 의 rustc 1.47.0 -O
은 두 기능에 대해 동일한 어셈블리를 생성합니다.
example::div:
push rax
test esi, esi
je .LBB0_2
mov eax, edi
xor edx, edx
div esi
pop rcx
ret
.LBB0_2:
lea rdi, [rip + str.0]
lea rdx, [rip + .L__unnamed_1]
mov esi, 25
call qword ptr [rip + core::panicking::panic@GOTPCREL]
ud2
example::safe_div:
push rax
test esi, esi
je .LBB1_2
mov eax, edi
xor edx, edx
div esi
pop rcx
ret
.LBB1_2:
lea rdi, [rip + str.0]
lea rdx, [rip + .L__unnamed_2]
mov esi, 25
call qword ptr [rip + core::panicking::panic@GOTPCREL]
ud2
그러나 NonZeroU32::get
0에 대한 결과 를 확인하는 것은 무의미하다는 것이 정적으로 알려져 있습니다. 어떻게 든 (어쩌면 새로운 창조와 최적화가 믿을 수 struct
이에 대한들)을 unsafe
덜 방법은?
관련 GitHub 문제 # 49572
답변
1 Ohad Dec 29 2020 at 14:46
귀하의 질문을 본 후 std에 필요한 s를 추가impl
했으므로 이제 야간 릴리스 (및 향후 1.51 안정 릴리스)에서이를 지원합니다!
Godbolt for
pub fn div(x: u32, y: u32) -> u32 {
x / y
}
pub fn safe_div(x: u32, y: std::num::NonZeroU32) -> u32 {
x / y
}
pub fn safe_rem(x: u32, y: std::num::NonZeroU32) -> u32 {
x % y
}
예상되는 어셈블리를 생성합니다.
example::div:
push rax
test esi, esi
je .LBB0_2
mov eax, edi
xor edx, edx
div esi
pop rcx
ret
.LBB0_2:
lea rdi, [rip + str.0]
lea rdx, [rip + .L__unnamed_1]
mov esi, 25
call qword ptr [rip + core::panicking::panic@GOTPCREL]
ud2
example::safe_div:
mov eax, edi
xor edx, edx
div esi
ret
example::safe_rem:
mov eax, edi
xor edx, edx
div esi
mov eax, edx
ret