It lives on the stack and is handed around by value, the question of ownership really only gets interesting once heap memory and pointers/references come into play.
I guess ancient C compilers would do a memory copy on return, but there are various optimizations in "newer" compilers which remove redundant copies, and structs up to 16 bytes or so are passed in registers anyway (via the 64-bit Intel and ARM ABI conventions).
The function that calls `new_point`, the value is moved. Similarly, consider the following case.
struct Point a = new_point();
struct Point a2 = a;
Assuming `struct Point` has a destructor, this would move `a` into `a2`, and prevent accesses to `a` after `a2` assignment, as `a` is no longer considered to be alive at this point. C++ has a wrong default of cloning instead of moving, but a new language could fix that.
It isn't. Cloning is what actually happens under the hood, if a and a2 are in different memory locations. Making a inaccessible after the assignment is merely a convention. With a struct that only has data members, there are no further consequences.
If the struct contains a pointer, you need a kind of additional contract that says how the memory that is pointed to is going to be managed, particularly when it is going to be freed and by whom. And that is where move semantics establish a constricting convention that is intended to make that unambiguous.
What part of Rust’s syntax do you think is a detriment vs C? A lot of it is very similar to C, but with ambiguity removed.
- Variable types are changed to avoid ambiguity in lexing.
- Loops and conditionals require {}, which means the parentheses can be dropped on the condition and there’s no ambiguity about nested if’s and else’s.
I guess ancient C compilers would do a memory copy on return, but there are various optimizations in "newer" compilers which remove redundant copies, and structs up to 16 bytes or so are passed in registers anyway (via the 64-bit Intel and ARM ABI conventions).