Post by i***@gmail.comPLEASE ASSUME THAT INT OCCUPIES 4 BYTES. <<
I compiled the code,
---------------------------------------------
#include <stdio.h>
struct s {
int a : 6;
_Bool b : 1;
_Bool c : 1;
_Bool d : 1;
_Bool e : 1;
_Bool f : 1;
_Bool g : 1;
int h : 12;
};
void main(void) {
"void main(void)" should be "int main(void)
Post by i***@gmail.comprintf("%d\n", sizeof(struct s));
"%d" should be "%zu".
Post by i***@gmail.com}
---------------------------------------------
and the output was a bit unexpected.
---------------------------------------------
12
---------------------------------------------
As stated by the C11 draft,
... If enough space remains, a bit-field that immediately follows
another bit-field in a structure shall be packed into adjacent bits of
the same unit... I expected it to fit into 4 bytes since I used a
32-bit compiler. Specifically, I used gcc (tdm-1) 5.1.0. Is it against
the standard?
This *might* be non-conforming. We can't be sure without seeing how the
bit fields are actually allocated. A compiler may legally add arbitrary
padding at the end of a structure, so the output you're seeing is
consistent with all the bit fields being allocated correctly. But it's
unlikely that a compiler would allocate more padding at the end of a
structure than is actually needed for correct alignment.
The output I get on several versions of gcc is 4, but I do get 12 using
tcc (this is on Linux x86_64). A version of your program that shows
where the bit fields are actually allocated indicate that tcc allocates
the 6-bit int bit field in one 32-bit word, the 6 _Bool bit fields in
another 32-bit word, and the final 12-bit int bit field in another
32-bit word.
Here's the program (it's a bit long):
#include <stdio.h>
#include <string.h>
static void dump(void *base, size_t size) {
for (unsigned char *p = base; p < (unsigned char*)base + size; p ++) {
printf("%02x", *p);
}
putchar('\n');
}
struct s {
int a : 6;
_Bool b : 1;
_Bool c : 1;
_Bool d : 1;
_Bool e : 1;
_Bool f : 1;
_Bool g : 1;
int h : 12;
};
int main(void) {
printf("sizeof (struct s) = %zu\n", sizeof(struct s));
struct s obj;
fputs("int a:6 ", stdout);
memset(&obj, 0, sizeof obj);
obj.a = -1;
dump(&obj, sizeof obj);
fputs("_Bool b:1 ", stdout);
memset(&obj, 0, sizeof obj);
obj.b = 1;
dump(&obj, sizeof obj);
fputs("_Bool c:1 ", stdout);
memset(&obj, 0, sizeof obj);
obj.c = 1;
dump(&obj, sizeof obj);
fputs("_Bool d:1 ", stdout);
memset(&obj, 0, sizeof obj);
obj.d = 1;
dump(&obj, sizeof obj);
fputs("_Bool e:1 ", stdout);
memset(&obj, 0, sizeof obj);
obj.e = 1;
dump(&obj, sizeof obj);
fputs("_Bool f:1 ", stdout);
memset(&obj, 0, sizeof obj);
obj.f = 1;
dump(&obj, sizeof obj);
fputs("_Bool g:1 ", stdout);
memset(&obj, 0, sizeof obj);
obj.g = 1;
dump(&obj, sizeof obj);
fputs("int h:12 ", stdout);
memset(&obj, 0, sizeof obj);
obj.h = -1;
dump(&obj, sizeof obj);
return 0;
}
and here's the output I get using gcc:
sizeof (struct s) = 4
int a:6 3f000000
_Bool b:1 40000000
_Bool c:1 80000000
_Bool d:1 00010000
_Bool e:1 00020000
_Bool f:1 00040000
_Bool g:1 00080000
int h:12 00f0ff00
Using tcc, I get:
sizeof (struct s) = 12
int a:6 3f0000000000000000000000
_Bool b:1 000000000100000000000000
_Bool c:1 000000000200000000000000
_Bool d:1 000000000400000000000000
_Bool e:1 000000000800000000000000
_Bool f:1 000000001000000000000000
_Bool g:1 000000002000000000000000
int h:12 0000000000000000ff0f0000
which I believe is non-conforming.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"