Reputation: 1157
On gcc/clang, long double
use 10 bytes but take 16 bytes. It'd be good if this struct is 16 bytes but it's actually 32 bytes, wasting half of bandwidth.
struct {
long double x;
int id;
};
I tried to union
two values, but since compiler assumes the whole 16 bytes used only by the long double
, editing it sometimes modifies int
.
Any good solution to pack them finely?
Upvotes: -1
Views: 177
Reputation: 181199
On gcc/clang,
long double
use 10 bytes but take 16 bytes.
I think you mean that the storage size of long double
is 16 bytes, of which only 10 are significant to its numeric value (so 6 are padding).
This would be primarily a property of the target ABI for which the compiler is building, not of the compilers themselves.
It'd be good if this struct is 16 bytes but it's actually 32 bytes, wasting half of bandwidth.
Have you considered using double
instead of long double
?
In any case, the union
is the only way that C provides for two or more live objects to have overlapping storage, where neither object comprises the other. That does not serve the purpose of storing two overlapping values simultaneously. Suppose you knew that the first 10 bytes of a long double
were the significant ones, and that the size of int
is 4. You might then imagine doing something like this:
union problemmatic {
long double x;
struct {
char padding[12];
int id;
}
};
But
x
writes only the 10 significant bytes, leaving the others alone, andx
and then writing to id
does not cause the stored value of x
to be a trap representationThat is, writing to either member could invalidate the other.
Bottom line: if you want to use less storage then use smaller data types (i.e. double
rather than long double
). If you're committed to the data types you're using now then their storage footprint is part of the package.
Upvotes: 1
Reputation: 1346
union {
long double x;
struct {
int reserved[3];
int id;
};
};
Upvotes: -1