Recently I stumbled over a comparison between Rust and C and they use the following code:
bool f(int* a, const int* b) {
*a = 2;
int ret = *b;
*a = 3;
return ret != 0;
}
In Rust (same code, but with Rust syntax), it produces the following Assembler Code:
cmp dword ptr [rsi], 0
mov dword ptr [rdi], 3
setne al
ret
While with gcc it produces the following:
mov DWORD PTR [rdi], 2
mov eax, DWORD PTR [rsi]
mov DWORD PTR [rdi], 3
test eax, eax
setne al
ret
The text claims that the C function can't optimize the first line away, because a
and b
could point to the same number. In Rust this is not allowed so the compiler can optimize it away.
Now to my question:
The function takes a const int*
which is a pointer to a const int. I read this question and it states that modifying a const int with a pointer should result in a compiler warning and in the worst cast in UB.
Could this function result in a UB if I call it with two pointers to the same integer?
Why can't the C compiler optimize the first line away, under the assumption, that two pointers to the same variable would be illegal/UB?
int foo = 0; f(&foo, &foo);
. This is perfectly legal C and it works as expected with your function returning1
. – Bywayrestrict
to tell it that updating a doesn't update the value b is pointing to, which needs to be included in the comparison to 0, hence the store to a that happens before the comparison needs to go ahead, whereas in rust the default assumption is restrict – Ametropia