Is `MaybeUninit::uninit().assume_init()` a UB when targetting wasm32?

Generally, the following is a UB:

let x: i32 = unsafe { MaybeUninit::uninit().assume_init() };

This is because the bit pattern is random and unstable. But in wasm the inital memory is zeroed. So the code above should not be a UB, if the optimizer is aware of the target specifics.

On the same note, in case if the compiler is aware of that, would [0; _] be a no op?

UB is definitionally not dependent on the target. It's a property of the code in the framework of the high-level language rules and the abstract machine that defines its operational semantics.

So, UB is UB on every platform (and without any platform, too).

7 Likes

So is it impossible to take advantage of platform specifics at all? Seems wasteful.

You can take advantage of platform specifics, but you should do so without causing UB.

The fact that allocations are 0'd by default is probably already used by the optimizer and/or the memory allocator without you having to do anything.

3 Likes

In this case x is not allocated in fresh wasm Memory, so this doesn't really help.

2 Likes

This doesn't even matter at all. The compiler will consider the memory as uninitialized and once you use assume_init() you assert that the memory has been initialized, which is not true and thus you get UB.

You may want to read

9 Likes

No, UB doesn't work like that.

List UBs is not contract between your program and hardware, but between you and the compiler.

People certainly think about what is predictable and what isn't predictable on the hardware level (or, if your platform is virtual, on the software level), but once the contract is written it couldn't be changed by one side without repecursions.

Sounds useful. How would you define “platform specifics”? If I would transmute address if function and look for some bit patterns in the generated code — is it still “platform specifics” or “foolishness”?

If I poke around in memory that's handled by memory allocator? Foolishness? But if you would open the documented for Turbo Pascal 5.x to 7.x you'll find it documented there!

Who decides?

In the end you have to have a list of “platform specifics” properties that compiler knows about, but it should be documented.

C/C++ compilers went in that direction and found that the end result satisfies no one.

That's why Rust tries to avoid adding bazillion knobs which would just make the whole thing unstable and yet still inefficient.

If you want to exploit some kind of “platform specifics” you have to talk to language developers and get some kind of documented way to exploit it. Because what if “platform specifics” for one would be “sheer stupidity that we would never support” for someone else.

People are different, you can not read someone's else mind.

2 Likes

The point is that:

let x: i32 = 0;

can't be optimized into something more efficient than normal on wasm, those 4 bytes have to be zeroed out because something else could have been there before.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.