News for hackers. Stuff that matters.
Re:Libghostty 1.0 by spacechild1 on Saturday November 07, 2026 @02:40AM (#50402503)
One example that comes to my mind is libopus: https://github.com/xiph/opus

If you have structs that might need to be extended, you can use "versioned structs". One popular technique is to include the struct size as the first field. The struct size is set to `offsetof(mystruct, lastmember) + sizeof(lastmember)` and the receiver of the struct can use this to check if a member exists. The ARA API is a good example: https://github.com/Celemony/ARA_API/blob/65ec5c43b943a48cb54...

Re:Libghostty 1.0 by agosz on Saturday November 07, 2026 @02:03PM (#50407052)
If you do version and size as the first two fields, you're basically there to backwards and forwards compatibility. Callers can request the size of the struct, allocate a buffer, and read out the parts they need. They can also check specific versions for what they support and ignore newer versions.

It also helps if you only append to the end of the struct for newer fields.

Re:Libghostty 1.0 by spacechild1 on Sunday November 08, 2026 @11:21AM (#50414573)
If you only access members, the version is not necessary. The receiver of the struct checks which members are present and ignores extra members that it does not know about. That's backward and forward compatibility.

The version could be useful if some members change their meaning across versions. But this would mean that you couldn't use a struct made from a future version because you wouldn't know about potentially changes.

Personally, I have only seen version or size, but not both. Do you have an example?

> It also helps if you only append to the end of the struct for newer fields.

This is actually required because changing or reordering existing members is an ABI break. Unless every version has its own dedicated struct. (This is often done in COM like APIs where interfaces are extended by adding a new interface. The client queries the must recent interface it knows about; if not supported, it tries the previous interface, and so on until it succeeds.)