Phil said:
I've needed to do almost precisely what I've mentioned in a RAM-
limited embedded environment. I don't view the assumption that
he might want to be doing the same to be a "more complicated" one.
I've never had need of that number; the only ways I can think of to use
it involve undefined behavior.
I have had situations where the number I mentioned would have been
useful, when packing a struct into an array of unsigned char. If there
had existed an packed_sizeof, my code could have been marginally
simplified by making use of it as in the following simplified example,
which references the struct abc provided by the OP:
int pack_abc(FILE *output, struct abc *padded)
{
unsigned char packed[packed_sizeof(struct abc)];
unsigned char *p = packed;
memcpy(p, &padded->z), sizeof padded->z);
p += sizeof padded->z;
memcpy(p, &padded->y), sizeof padded->y);
p += sizeof padded->y;
memcpy(p, &padded->x), sizeof padded->x);
return fwrite(packed, 1, sizeof packed, output);
}
In the actual case where I had to do something this, the equivalent of
the fwrite() function was actually a third-party library routine, which
by a different route required a text string describing the types of the
objects that had been packed into the buffer - similar in concept
(though not in syntax) to the format strings used by the
printf()/scanf() family. The structure had sufficiently many fields that
it made sense to combine the memcpy() and the p+= into a single macro.
However, I didn't want to complicate things by showing those details.
Note: the advantage provided by having a packed_sizeof in this case is
quite minor, and I wouldn't advocate it's addition to the standard, but
I could easily imagine someone else wanting such a thing for similar uses.