I am just a beginner in rust program, I was just trying to understand how data are stored in memory. Then I found a behavior for tuple. I couldn't understand why this is happening , please point me in right direction why this is happening??.
// main program
fn main() {
let tup: (i32, i32, u8) = (500, 2, 1);
mem(&tup); //same memory adress of "tup.0" ..ah fine predictable
mem(&tup.0);
mem(&tup.1);
mem(&tup.2);
println!();
//The variable "tup" points to adress of "tup.1" not "tup.0" Why???
//Is it because memory for "tup.1" than "tup.0" is larger??
let tup = (500, 6.11, 1);
mem(&tup); //same memory adress of "tup.1" ????
mem(&tup.0);
mem(&tup.1);
mem(&tup.2);
println!();
// If the above condition was true then why "tup" didnt point to "tup.2" in this scenerio???
let tup = (500, 1, 6.11);
mem(&tup); //same memory adress of "tup.0"
mem(&tup.0);
mem(&tup.1);
mem(&tup.2);
println!();
Be aware that there are no guarantees around the layout of most Rust types (though you can tell Rust to use C's layout instead). What you observe today may change tomorrow without warning.
With that caveat out of the way, let's take @Cerber-Ursi's advice and look at both the size and the alignment: Playground
Now we can make educated guesses at what's going on.
In the second tuple, it's moving the align-to-8 member to the top as that's the align of both .1 and the tuple as a whole. If it didn't reorder, it would need padding between .0 and .1, because .0 is only 4 bytes.
In the third tuple, the align situation is similar, but no reordering is needed to avoid padding because the sizes of fields .0 and .1 add up to 8 (so .2 will be aligned). This means that in the second tuple, it could have swapped .1 and .2 instead of .1 and .0.
The sizes of the three tuples are 12, 16, and 16. Next let's try with #[repr(C)], which will make the compiler keep fields in order.
Tuple 1 and Tuple 3 look the same
Tuple 2 is now 24 bytes -- 8 bytes larger
You can see from the offsets that there's 4 bytes of padding between .0 and .1 now. That's expected from the alignment considerations. Where are the other 4 bytes from? They're at the end, after .2, to ensure that the size of the tuple is a multiple of its alignment. (Though even this layout consideration may change some day!)
So now we see that by reordering the second tuple, the compiler made the size 8 bytes smaller.
Ah I think your guess is right maybe that is what going on behind the scene. And also thanks for code formatting introduction I was also looking for that.