struct {
char str[4];
char sc1;
char str2[3];
char sc2;
} foo __attribute__((packed));
snprintf(foo.str, 5, "%04X", data);
foo.sc1 = ';';
snprintf(foo.str2, 4, "%03X", otherdata);
foo.sc2 = ';';
Yes, I know that both snprintf() calls in the above snippet will overflow their immediate buffer. Yet this code is safe; the network protocol for which this code is written does not actually need nor expect NUL bytes; instead, it wants semicolons. I could of course use a "char foo[9]" rather than a struct as above, but I find this to be slightly more convenient than to count offsets.
However, this code does not work with glibc, because the buffer overflow detection kicks in.
Solution:
char buf[5]; snprintf(buf, 5, "%04X", data); memcpy(foo.str, buf, 4);
In other words: add a stupid and useless memcpy, because someone thinks they're smarter than me. Stupid morons.