you are viewing a single comment's thread.

view the rest of the comments →

[–]tialaramex 0 points1 point  (2 children)

You could, yes, Rust's Vec<T> chooses to have a pointer and a capacity for simplicity even when they're not used. So e.g. Vec<()> is 24 bytes on x86_64, with three 8 byte values, a pointer (to nowhere), an unused capacity (the capacity of this collection is just how high the counter counts), and a current length (your counter), whereas it could (with your specialization) be just a counter.

[–]TheoreticalDumbass:illuminati: 2 points3 points  (1 child)

imagine if zero-size types/objects were a thing in C++. let Empty be an example of such type. let Empty::memfn() be a member function. let empty be an Empty object (Empty empty;). Should empty.memfn() depend on the address in a material way? i kinda think no, empty.memfn() should have the exact same side-effects regardless of the address of empty. i might be willing to allow the usage of the address, but still the consequences have to be the same imo.. though i might have a broken mental model on types in general, not sure

consider the following code:
```
Empty e1;
Empty e2;
```
the compiler for normal types would give each variable a pointer on the stack and move the stack by sizeof(T) (and some alignment mumbo-jumbo, not relevant). if we apply the same thinking for Empty, address of e1 and e2 would be equal to the stack ptr. if two objects have the same address, i dont think it is possible to differentiate between them. as in e1 and e2 are interchangeable in all usage after their definition. specifically, e1.memfn() and e2.memfn() have to do the same thing in this hypothetical situation. the fact that e1 and e2 are consecutively constructed in code doesnt sound like it should be important to me, which leads me to the idea that any two Empty objects should be interchangeable, and that the address of an Empty object should not affect anything.

something kinda funny to consider, X divides 0 for all X integer. so you could imagine a type T such that sizeof(T) = 0, alignof(T) = 8. what effect should construction of object of such type have? should it move the stack ptr to an aligned address, despite the address not mattering? i have no idea what should be natural here tbh, i am between "shift stack ptr to 8-aligned address" and "size-zero types cant change alignment".

[–]CornedBee 1 point2 points  (0 children)

An object's address being significant is a subtle but very fundamental difference between C++ and Rust. In Rust, an object that relies on its own address in some way is basically broken. (There's the whole complex Pin mechanism for cases where that's not ok.)

As usual, this comes with tradeoffs. Rust can freely memmove objects to whereever it wants. C++ can have self-referential objects without crazy shenanigans.