2

I have these two structures :- 1.

typedef struct bitfield
{
    unsigned int a:16;
    unsigned int b:17;
    union
    {    
        unsigned int c:4;
        unsigned int d:32;
    };
}bfield;

This structure has anonymous union, when i calculate the size of this structure - it comes out to be 12 bytes (4+4+4). This is fine.

2.

typedef struct bitfield
{
    unsigned int a:16;
    unsigned int b:17;
    union u
    {    
        unsigned int c:4;
        unsigned int d:32;
    };
}bfield;

But my DevC++ compiler on 32 bit machine prints 8 bytes for this structure's size. I don't understand why it comes out to be 8.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
instance
  • 1,366
  • 15
  • 23
  • There are almost no guarantees about the layout of a bit-field. Said that: with 32 bit `unsigned` your `struct` can only have 8 bytes if your bytes are more than 8 bits wide. Please provide a [mcve]. Assuming 8 bits/byte, the `struct` size can very well be 16 bytes. But that all depends on the platform. – too honest for this site Sep 23 '16 at 14:25
  • @Olaf default width of unsigned is not relevant since he/she has manually specified the bitwidth of each field. But I nevertheless agree that it is not possible to pack this into only 8 bytes. It would be intresting to see what code the compiler is generating. – jforberg Sep 23 '16 at 14:52
  • But I get the same result as OP: goo.gl/ASQO6Q – jforberg Sep 23 '16 at 14:57
  • @jforberg: "There are almost no guarantees about the layout of a **bit-field**" - Please read comments carefully. Then read the standard and have a look at various implementations! – too honest for this site Sep 23 '16 at 15:00
  • 1
    @jforberg: How can you get the same result, as we don't even know the code OP uses? – too honest for this site Sep 23 '16 at 15:01
  • 2
    @Olaf: I don't understand what you mean. OP is asking **why** this is happening when using the popular GCC compiler on the popular Intel 32 platform. This is a perfectly valid question. If you don't know why then that's OK but please don't tell me to "go read the standard". Or assume that I didn't read your comment before replying. Or imply that any "other code" that OP has might change the sizeof a previously defined struct, which is patently false. – jforberg Sep 23 '16 at 15:06
  • @jforberg: I don't see where he mentions gcc or Intel. Not even x86. I told you rtfm, because you did not understand my comment. feel free to answer. But h question is incomplete. Also you edit is wrong. The 2nd is not a named `union`. – too honest for this site Sep 23 '16 at 15:28
  • 1
    @Olaf He stated he is using Dev-C++, an IDE which uses GCC (mingw) and only runs on Windows. He also stated that his machine was 32-bit. So I thought it was safe to assume his platform from that, but apparently it was not enough to satisfy the language lawyers of stack overflow. In any case, I think we have spent quite enough time talking to each other. Good day to you. – jforberg Sep 23 '16 at 15:36
  • The standard doesn't set a standard for bitfield implementation, I've found it better to do it manually, this way you know what you are getting: http://stackoverflow.com/questions/11815894/how-to-read-write-arbitrary-bits-in-c-c/27592777#27592777 – dtech Sep 23 '16 at 16:15

2 Answers2

6

Your first example declares a structure with an anonymous union.

The second example declares a structure which contains the declaration of an union, which is a noop. E.g.

typedef struct bitfield
{
    unsigned int a:16;
    unsigned int b:17;
    union u
    {    
        unsigned int c:4;
        unsigned int d:32;
    };
}bfield;

int main(void) {
    struct bitfield b;
    b.c=2;
}

will fail with

x.c:14:4: error: 'struct bitfield' has no member named 'c'

Compiler might warn about it with

x.c:9:6: warning: declaration does not declare anything

So, your question has nothing todo with bitfields but with anonymous unions.

ensc
  • 6,704
  • 14
  • 22
2

The declaration of the union in the OP is incorrect (it does not do what the OP wants to).

It appears as just a declaration of an union, and does not add a field to the structure.

Either declare the union field as anonymous, or as named.

Please see this example (also posted here: http://rextester.com/EPUEH77041 )

In both cases the size of struct is 12 bytes.

#include <iostream>

typedef struct bitfield
{
    unsigned int a:16;
    unsigned int b:17;
    union u
    {    
    unsigned int c:4;
    unsigned int d:32;
    }U;
}bfield;


typedef struct bitfield2
{
    unsigned int a:16;
    unsigned int b:17;
    union
    {    
    unsigned int c:4;
    unsigned int d:32;
    };
}bfield2;

int main()
{
    std::cout << "Test bitfields1\n" << sizeof(bfield) << "\n";
    std::cout << "Test bitfields2\n" << sizeof(bfield2) << "\n";

    static volatile bfield y;
    y.a=0x1234;
    y.b = 0x1FF55;
    y.U.d = 0x5a5a5a5a;
    std::cout << std::hex << y.U.d << "\n";

    static volatile bfield2 x;
    x.a=0x1234;
    x.b = 0x1FF55;
    x.d = 0x5a5a5a5a;
    std::cout << std::hex << x.d << "\n";
}
ddbug
  • 1,392
  • 1
  • 11
  • 25