Std::mem::transmute returns different values between architectures


#1

This code returns different answers between different architectures. Are these correct ?

I want this code to return same answer despite any architecture. Do I miss something?

Returns on x86_64-linux-gnu (Little endian):

length: 4
val: 204 187 170 0
length: 8
val: 255 238 221 204 187 170 0 0

Returns on powerpc-linux-gnu (Big endian, 32-bit):

length: 4
val: 0 170 187 204
length: 8
val: 0 0 170 187 204 221 238 255

I (cross-)compiled the code on a x86-64 machine and ran on each machine.
Cross compiler was built like following:

# rust
git clone https://github.com/rust-lang/rust.git
cd rust
./configure --target=powerpc-unknown-linux-gnu
make
make install

# cargo
git clone https://github.com/rust-lang/cargo
git submodule update --init
./.travis.install.deps.sh
./configure --local-rust-root=/usr/local \
make
make install

cd ~/.cargo
echo '[target.powerpc-unknown-linux-gnu]\n\
linker = "powerpc-linux-gnu-gcc"' > config

Thank you.


#2

As I can guess, this is quite correct behavior, as you shift your view on integer types to an array of bytes, and underlying bytes are ordered differently for big- and little-endian machines, that is it just reflects real bytes order, and it’s quite logical for me.


#3

You need to decide whether you want the result in your vec to be big-endian or little-endian. If you choose little endian you can use u32::to_le to make sure your integer is in little-endian byte order before you transmute. There are also to_be, from_le and from_be which might be helpful.


#4

Thank you for your replies. I could understand the behavior of the function.

Here is some background:
I’m writing code using std::hash::sip, in which std::mem::transmute is used. The code works well on a x86-64 but doesn’t on a PowerPC. I’ll recheck my code to get it works fine.

Again, thank you for your help!