Advantage
Packing data is possible, both to the compiler and the user. An extreme example of this are u1
ints, a.k.a, booleans (as one bit unsigned integer has only two possible representations).
So if your language is focused or has an option to optimize to size (code or memory), this can be relevant. You can possibly pack 8 sequential booleans in a octec, instead of 8 sequential int_fast_t
(the performante choice) that in some machines will be wasteful as 8x64 = 512 bits.
Disadvantage 1: slow
It will be slow. To the point that the users complain about it.
Modern languages gives integers that are power of two, multiple of octets because modern CPUs have them. And because CPUs have then, they are fast. As in hardware fast. As in there is nothing more fast than this is possible fast. And users like that.
Disadvantage 2: trashed on multithread
You may encounter situations where your compiler (or someone compilers) do the packing sometimes, but sometimes not. The problem with packed data is that CPUs may don't have how to write on packed data in an atomic way. The CPU will need to load the whole word, bitfidle it to simulate the partial write, and write back the whole memory world.
So, sometimes an a.b = true;
in one thread, a.c = false;
in another, in a packed struct, will result in impossible to reason results, another name for undefined behaviour.
FIXED BIN(10)
$\endgroup$