preprocessor-toolchain · intermediate · ~15 min
Validate struct memory layout and binary serialization alignment with compile-time assertions.
Binary protocol and serialization headers depend on exact struct layout and alignment. In C11, _Static_assert (or static_assert from <assert.h>) catches struct padding and size mismatches at compile time rather than crashing in production.
Given the protocol requirement:
sizeof(PacketHeader) == 8.Define the struct:
typedef struct {
uint32_t stream_id;
uint16_t length;
uint8_t flags;
uint8_t version;
} PacketHeader;
And implement validator functions:
size_t get_packet_header_size(void);
int pack_packet_header(uint32_t stream_id, uint16_t len, uint8_t flags, uint8_t ver, PacketHeader *out);
get_packet_header_size: return sizeof(PacketHeader).pack_packet_header: if out == NULL, return -1. Otherwise populate all four struct fields and return 0.sizeof(PacketHeader) == 8.PacketHeader hdr;
pack_packet_header(1, 100, 0x01, 1, &hdr); // returns 0
get_packet_header_size(); // returns 8
stream_id: 32-bit int; len: 16-bit int; flags: 8-bit int; ver: 8-bit int; out: pointer to PacketHeader.
Returns 0 on success, -1 on NULL pointer.
sizeof(PacketHeader) must strictly equal 8. Verify with _Static_assert.
#include <stddef.h>
#include <stdint.h>
typedef struct {
uint32_t stream_id;
uint16_t length;
uint8_t flags;
uint8_t version;
} PacketHeader;
size_t get_packet_header_size(void) {
return 0;
}
int pack_packet_header(uint32_t stream_id, uint16_t len, uint8_t flags, uint8_t ver, PacketHeader *out) {
(void)stream_id; (void)len; (void)flags; (void)ver; (void)out;
return -1;
}
Ordering struct fields with internal padding; forgetting _Static_assert.
NULL destination pointer returns -1; exact size 8.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.