This isn't true of modern processors.
struct S {char data, char pad0, char pad1, char pad2};
int main() {S dataStruct; printf("%s", dataStruct.data); return 0;}
and give me a 4-byte struct or would the compiler optimize it all away and leave me with a 1-byte struct?Well, I chose this example specifically to ask whether the resulting memory structure, completely independent of calling a sizeof(), would still be as if I were to call a sizeof() (which then I believe would be 4 bytes large) if not accessing the total size of the struct or any of the padding members.
It makes a difference in the memory footprint, which can become important, if you're programming a device with just 64-bytes total RAM.
struct st s;
bzero(&s, sizeof(s));
// ...
write(fd, &s, sizeof(s));
I’ve dealt with many systems that have tons of unnecessary serialization logic, and found them slower and buggier than just letting the C spec define the data format.Having said that, it is possible to get this sort of thing right with C++ and templates (thanks to inlining).
Higher-level languages without compile time code generation (like Java and Python) usually make serialization a train wreck in comparison with “send raw structs” or “make the [C++] compiler generate and typecheck the machine code that does the serialization”
You can get away with directly writing a struct for simple structs, but eventually it will bite you.
The remaining issue is endianness, but you can configure ARM to match x86 at boot so shrug.
Also, if I tell any reasonably experienced developer my protocol sends a packed struct with these fields:
uint8_t version
uint16_t reserved
uint8_t op
int32_t status
uint32_t data_length
// void data[]
They’ll be able to write a correct deserializer in pretty much any language, and can probably write it in ~ 10 lines of code.I agree that packed structs can be tricky, but they’re much better than the vast majority of serialization libraries I’ve dealt with (including all of the open source ones, and I’ve used all the usual suspects).
The big annoyance is network people all use big endian probably just to spite everyone else.
The people that wrote that spec knew that and went with big endian anyways.
Also I work with people that do network hardware. They can't care less about little or big endian. Makes no difference to them.
ARM in BE mode is pretty rare / nonexistent. Small MIPS chips still float around in mostly low-end networking gear, though, and those do tend to run in BE.