I have a C function which receives u32 pointer and writes there its answer. But variable where I want to store it is usize. I can use one of two approaches:
But I am not sure that it is safe to read the size variable after I had written to it via downgraded pointer. It works but will it be safe on all architectures with different endians?
This is undefined behaviour (in C as well), due to aliasing rules. A compiler is free to assume that the usize and the u32 simply do not reside in the same memory and optimize using that assumption, so it’s not even guaranteed to behave correctly on little endian systems.
In other words, don’t do 2. Create a temporary. Unless you’re on a super hot path, the performance difference is negligible.
Side note: big endian systems are basically non-existent nowadays.
Hmm, actually, I retract my previous comment, Zig does not actually do strict aliasing (as opposed to C), at least as of this thread from last year. So it might be legal.
That means @AndrewKraevskii’s comment stands, even though big endian systems these days are few and far between.
It looks like this would be technically correct… but, I don’t see why you’d want this? It would certainly break when compiled with the C backend.
Tbh I am trying to achieve “better syntax” at a cost of shooting my leg
I have a C api which returns me array of data. Size of it is written to a pointer passed as parameter. But parameter is u32 and not usize so I am just creating new slice and pass there &slice.len which I need to downgrade…
This is not the Zig way. The Zig way is to achieve best syntax while not shooting yourself in the leg. If you have not reached this peak, you have more to learn. It is possible to achieve.
Not sure if you aware of the caveats with doing this, but manually changing the len field of a slice is not often something you want to be doing if your slices are heap-allocated. That may not be your case here, but this is what you can expect if so, and you don’t implement the logic to change it back to the actual capacity before freeing.
Thanks for one more method. When compiled on ReleaseFast it outputs basically the same assembly without using fancy magic in source code… But I think I will stick with my gun powered spaghetti monster because I also need to deconstruct the slice at some point for C API which would otherwise fail on BE…