Size of empty struct in rust

I'm from C++ background . in C++ , empty class has size of 1 Byte. This is because C++ requires every object to have a unique memory address, even if it doesn't have any data or member variables. But in Rust empty struct has size Zero. considering Rust is a similar language like C++ then why the size of empty struct in rust is zero.

According to The Rust Reference, the default representation for composite types (structs, enums, etc) in Rust obey the following three conditions:

  1. The fields are properly aligned.
  2. The fields do not overlap.
  3. The alignment of the type is at least the maximum alignment of its fields.

Zero-size structs don't break these rules, so they are allowed to exist to save space.


Also have a look at the ZST section in the nomicon.


In Rust, an empty struct (also known as a zero-sized type or ZST) has a size of zero bytes, which is different from the behavior in C++ where an empty class has a size of at least one byte. There are several reasons for this distinction:

  1. Address uniqueness: While C++ mandates that every object must have a unique memory address, Rust doesn't impose this requirement. As a result, Rust's compiler can optimize empty structs to have zero size.

  2. Language design: Rust's design enables the use of zero-sized types, whereas C++ does not. ZSTs in Rust serve various purposes, such as implementing marker traits, tags, and other compile-time constructs. These types are primarily utilized for type-level programming and don't incur any runtime overhead.

  3. Optimization benefits: The Rust compiler is designed to optimize empty structs to have zero size, which can result in improved performance and reduced memory usage. This is especially beneficial when dealing with a large number of empty structs in your code.

It's worth noting that even though Rust's empty structs have a size of zero bytes, the compiler can still ensure unique addresses for distinct instances of an empty struct when required, such as when used as a field in another struct or when dynamically allocated on the heap. This is achieved through compiler optimizations and layout calculations.


Also note that C++20 added [[no_unique_address]] to allow for true zero sized fields.


(Also, base class subobjects in C++ have always been permitted (since at least C++98) to have zero additional size, if they have no fields. It's only the most derived object which must have nonzero size.)


I guess the ploy worked a tiny bit too well if people are asking such questions.

The best short characterisation of Rust would be: “an ML dialect in a C++ trenchcoat”.

Rust borrowed lots of it's syntax from C++, that's true. That's why it have enums and not coproducts, e.g.

But if we are talking about semantic then it doesn't follow C or C++ rules. In particular it's unit type is not special (unlike C/C++ void) and that one, naturally, have size zero.

And once you have allowed one type to have zero size it's not that hard to allow more zero-sized types.

I'm not sure what you mean by this, but ZSTs as fields are still zero-sized and can have the same address as another field, Box of ZST doesn't allocate (and typically collections don't either) and their pointers-to-ZST can be the same, etc. Pointer identity is pretty meaningless in the face of ZSTs (and also fraught in the face of wide pointers).


This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.