#include <stdio.h>
#include<stddef.h>
int main(){
typedef struct aptmpl {
int a;
int b;
int c:28,
Note: in ordinary declarations, 'int' is the same as 'signed' int'.
However, when plain 'int' is used as a bit-field type, it's
implementation defined whether the corresponding bit field is signed or
unsigned (6.7.2p5). It is seldom, if ever, a good idea to be unsure
about whether a variable is signed or unsigned, so it's usually best to
explicitly use either 'unsigned' or 'signed' when declaring bit fields.
I will assume, below, that 'c' is signed; by a convenient accident, my
code will do what it's intended to do, even if c is unsigned - but I
wouldn't recommend counting on such accidents.
You mention portability down below. Keep in mind that 'int' can have as
few as 16 bits, in which case int c:28 violates a constraint
(6.7.2.1p2). You can't portably declare a bit field to have any type
larger than int, and therefore you can't portably define a bit field
with more than 16 bits.
d:1,
e:1,
f:1,
g:1;
} APTMPL;
printf(" the location si %d\n", offsetof(APTMPL, c));
}
I get the following error
p1.c: In function âmainâ:
p1.c:15: error: attempt to take address of bit-field structure member
âcâ
IS there any way , I can get the offset of a bit field, directly.
( should be portable code)
No.
And yes, sort of:
struct aptmpl s;
memset(&s, 0, sizeof s); /* clear every bit of every byte of 's' */
s.c = 0x7FFFFFF; /* set every value bit of 'c' */
unsigned char *p = (unsigned char*)&s;
size_t off1, off2;
for(off1=0; off1 < sizeof s && !p[off1]; off1++);
/* You can't assign a single value to c that sets all the value
* bits and the sign bit, without making assumptions about
* whether signed integers use a 2's complement, 1's complement,
* or sign/magnitude representation, all three of which are
* explicitly permitted by the standard. If you're willing to
* assume a particular representation, then only one loop
* would be needed.
*/
s.c = -1; /* set the sign bit of 'c' */
for(off2=0; off1 < sizeof s && !p[off2]; off2++);
/* there's no guarantee that the sign bit is stored in the first
* byte, or in the last one (or indeed, anywhere else
* in between).
*/
if(off2 < off1)
off1 = off2;
At this point, off1 identifies the offset of the first byte in 's' whose
value was affected by setting any of the sign or value bits of 's.c'. On
systems where int is a type with more than 32 bits, this might be a byte
containing only padding bits. This might be a byte containing bits from
'c', but also bits that represent d, e, f, or g. With those issues in
mind, what in the world do you want to do with it?
I strongly suspect that you don't have a reason for wanting to know this
number, that makes sense for code that's intended to be portable.