0

Some simple Rust code:

struct Point {
    x: f64,
    y: f64,
}

fn main() {
    let p: &Point = &(Point { x: 0.3, y: 0.4 });
    // println!("{:?}" , p->x); // no sugar here for Rust
    println!("{:?}", (*p).x);
    println!("{:?}", p.x); // sugar?
    // no leak right? thanks Rust
}

And some similar C code

#include <stdio.h> 
#include <stdlib.h> 

typedef struct Point Point; 

struct Point {
    float x;
    float y; 
};

int main() {
    Point __tmp = { 0.3, 0.4 };
    Point* p = &__tmp;

    printf("%f\n", p->x); // C sugar for below
    printf("%f\n", (*p).x);
    // below doesn't work because p is a pointer to a point
    //printf("%f", p.x); // error: request for member 'x' in something not a structure or union
    // memory leak at this point right?
    return 0; 
}

It seems that p is a pointer to a Point in both pieces of code.

I want to make sure that Rust implementing p.x is (or can be thought of as) syntactic sugar and that I don't have a fundamental misunderstanding of what is going on.

Is this what they mean by aliasing? Is p in Rust more like an alias?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
user25064
  • 2,020
  • 2
  • 16
  • 28

1 Answers1

4

p.x is indeed sugar in a certain sense. Rust automatically dereferences any type that implements the trait Deref or DerefMut(depending on whether the context requires a mutable or immutable reference), when doing method/attribute look-up.

In your example, the reference &Point implements Deref<Target=Point>, so your p.x expression is expanded to (*p).x. Note that this only works, as long as the pointer type does not have an attribute/method named x of its own (which is not the case for a simple reference).

There is another question on SO that goes on about the detailed rules for auto-dereferencing.

Emilia Bopp
  • 866
  • 10
  • 20