# What's the maximum amount of fields could one struct contains?

I know asking about this problem may be foolish, but I decided to generate a struct by macro, which may not be a small amount. Except struct, what about tuple? Are the amounts the same?

There is no limit.  E.g.

``````macro_rules! large_tuple {
([\$(\$contents:tt)*] . \$(\$t:tt)* ) => {
large_tuple!([\$(\$contents)*, \$(\$contents)*] \$(\$t)*)
};
([\$(\$contents:tt)*]) => {
(\$(\$contents)*)
};
}

macro_rules! large_struct_con {
([\$(\$contents:tt)*] . \$(\$t:tt)* ) => {
large_struct_con!([\$(\$contents)*, \$(\$contents)*] \$(\$t)*)
};
([\$(\$contents:tt)*]) => {
Large(\$(\$contents)*)
};
}

fn main() {
let x: ((), (), (), (), (), (), (), ()) = large_tuple!([()] . . .); // 2^3 = 8

let y = large_tuple!([()] . . . . . . . . . . . . . . . . .); // 2^17 = 131072
let v = y.131071;

let y1 = large_tuple!( . . . . . . . . . . . . . . . . .); // 2^17 = 131072
let v1 = y1.131071;

println!("{v1}");

let z: Large = large_struct_con!( . . . . . . . . . . . . . . .); // 2^15 = 32768
println!("{}", z.12345);
}

macro_rules! large_struct {
([\$(\$contents:tt)*] . \$(\$t:tt)* ) => {
large_struct!{[\$(\$contents)*, \$(\$contents)*] \$(\$t)*}
};
([\$(\$contents:tt)*]) => {
struct Large(\$(\$contents)*);
};
}

large_struct!([i32] . . . . . . . . . . . . . . .); // 2^15 = 32768
``````

Rust Playground

1. Well… or rather, the first limit you’ll encounter is the compilation getting slower and slower, I guess; so I wouldn’t know if –say – more than `u32::MAX` many fields are allowed, but that’s an absurdly high number. ↩︎

1 Like

Wouldn't the limit actually be the size of the stack ? Similarly to arrays ?

The size of the stack at runtime hasn't got much to do with how many fields the compiler allows. The compiler can allow as many fields as field descriptors fit in the memory of the computer the compiler is running on.

I see, if so I'm relieved. My macro is unlikely to generate that much fields. Thanks.

I know, but practically speaking, a struct larger than the stack couldn't be initialized in (current) Rust

I think it won't. If so, we couldn't have a vector contains more bytes than stack size, even I have many GBs on my memory.

You can use unsafe code with raw pointers to initialize it field-by-field on the heap. The only thing you actually cannot do with a struct larger than the stack is, well obviously, storing it in the stack. (And Rusts idiom to typically construct structs in the stack first and only then move them to the heap does mean that avoiding ever storing any instance of the struct in the stack is significantly less ergonomic, or at least requires some good library support to make it ergonomic nonetheless ).

1. on a related note, there are libraries that try to make C++-style in-place construction and non-movable data structures easier to pull off, and such libraries should also be able usable for avoiding blowing up the stack with a huge struct ↩︎

3 Likes