Ok. The chain starts with
d. To write out the binding in full, we have:
// At address 9:
let d: Box<i32> = Box::new(5); /* = 2^30 - 1 */
d is at 9, pointing to 230-1.
We than take the address of
// At address 10:
let e: &Box<i32> = &d; /* = 9 */
And then we call
baz and the wheels fall off because of something I don’t think the book has explained to that point. See,
baz takes a
e is a
&Box<i32>. In order to make this work, the compiler does something called “deref coercion”. Basically, it “unwraps” the
Box to get at the pointer inside of it. If you have
Ptr is some kind of pointery thing, and ask for a
&X, the compiler will repeatedly unwrap the layers of pointery-ness until it finds a plain old
&X. So the actual chain goes
&Box<i32> (= 9) →
&i32 (= 230-1).
As a result, I think
f should actually be 230-1: it’s the same value as the box, not a pointer to the box (which would be 9. And certainly not 4, which I can’t even work out how that happened at all.
Looks like a bug in the explanation.