2

I'm reading source code of spl-token these days, and I've noted that #[repr(C)] is always added to structs and enums. For example, here is the token account struct of spl-token, and it has #[repr(C)] added.

I just learned that data layout (like alignment, padding...) is deterministic when using C representation. While the default Rust representation may in theory be changed, which means data layout from different versions of Rust compilers are not guaranteed to be the same. This in turn makes it difficult to do things like: when doing CPI, the invoked program is compiled using an older version of Rust compiler, and the Rust representation is changed by Rust Dev Team. So the invoking program (compiled with newer Rust compiler) doesn't know the data layout of the invoked program.

Is my understanding correct? Or is there any other reason Solana Dev Team adds #[repr(C)] to structs and enums?

1 Answer 1

3

It looks like you got a great answer on what repr(C) does in general at https://stackoverflow.com/a/77992499/16310679, so I'll answer the second bit of "why".

As the answer mentions, the Rust team reserves the right to change what repr(rust) means at any time, so structs that use repr(rust) do not have a stable layout in memory.

Since SPL token, and most Solana programs, write data into accounts, the layout of that data must not change. Otherwise, if a program is upgraded between two versions of Rust with a breaking change to repr(rust), it might not be able to deserialize its own account data. There are ways to mitigate this through serialization formats like borsh and bincode, but not everyone uses those.

So to make sure that the data layout of the type never changes, the structs use repr(C).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.