for me, keeping the struct keyword there just means one less thing to wonder/worry about when i’m dealing with code. it’s a way i signal to myself that i have the full definition of that struct available at that place in the code and could either stack or heap allocate it. i use typedef’d structs to indicate to myself that i do not have the definition available and thus can only refer to the type via opaque pointers.
when i started out as a C programmer, i typedef’d everything and would enforce the opacity of structs all over my codebase, but i found over time that it just served to complicate things. bare structs are simpler imo.
also, wrt serialising structs or other data: if you’re going to write anything to disk, you need to figure out a format for doing so. the easiest method is just to write structs themselves as binary data out to a file.
struct thing {
int x, y, z;
}
struct thing t = {.x = 42, .y = 24, .z = 0};
fwrite(&t, sizeof(t), 1, some_file);
the problem is that now you not only have a dependence on your data types and arrangement, but you also have a dependence on your CPU bits (32 vs 64, can change the size of int), CPU endianness (generally little, but this will bite you when you least expect it), and even your compiler (padding/alignment). and, what if you want to add more variables at a later date? you’ll need some metadata for versioning, at the very least. and what about interop with other applications or languages?
using a serialisation format which is independent of your in-memory representation is, in my opinion, always a good idea. convert to/from said format at the file loading/saving boundary of your application, and deal with versioning there.
as an example, i have a VST synth I’m developing for which I use JSON as the serialisation format (patches look like this if you’re curious). i have a version property that lets me transparently convert old presets to new ones on load, and it’s been a huge win for me because i can compartmentalise all of that logic in the loader. the rest of the synth logic doesn’t have to know anything about it.
and, on the subject of serialisation formats: msgpack looks cool. at work we use CBOR, which is very similar to msgpack except it’s an IETF RFC.