Topic
1 reply Latest Post - ‏2011-05-08T15:36:13Z by SystemAdmin
SystemAdmin
SystemAdmin
196 Posts
ACCEPTED ANSWER

Pinned topic sizeof (<struct with char bit fields>) == 4, no 1

‏2011-05-08T12:38:14Z |
Hi

> uname -a
AIX ep5512b 1 6 000497A2D900

> xlC -qversion
IBM XL C/C++ for AIX, V10.1
Version: 10.01.0000.0000

Hi

//

foo.cpp

#include <iostream>
struct Foo
{
unsigned char m1:1;
unsigned char m2:7;
};
int main()
{
std::cout << sizeof(Foo) << std::endl;
return 0;
}
//


> xlC foo.cpp
// No errors

> ./a.out
4 // not 1
// ==========
sizeof(Foo) on most of compilers is 1.
Do we have a way to say to compiler that sizeof(Foo) should be 1?

Thanks

Alex
Updated on 2011-05-08T15:36:13Z at 2011-05-08T15:36:13Z by SystemAdmin
  • SystemAdmin
    SystemAdmin
    196 Posts
    ACCEPTED ANSWER

    Re: sizeof (&lt;struct with char bit fields&gt;) == 4, no 1

    ‏2011-05-08T15:36:13Z  in response to SystemAdmin
    Hi,
    actually, the sizeof operator is correctly reporting the amount of space that the Foo structure is consuming, so if I can rephrase your question, you're asking "why does this IBM IAX xlC compiler allocate 4 bytes for struct Foo when the fields m1 and m2 consume 8 bits (1 byte)?"

    The compiler is rounding up the size to the nearest word. It will pack in as many fields as it can in a given word, but the size will be rounded up. For instance, if we write a modified version of your example:

    
    #include <iostream> struct Foo 
    { unsigned 
    
    char m1:1; unsigned 
    
    char m2:7; 
    }glob1; struct Fooplus 
    { struct Foo; unsigned 
    
    char m1:1; unsigned 
    
    char m2:7; 
    
    char blah; 
    
    char blah2; 
    } glob2; 
    
    int main() 
    { std::cout << 
    "Foo is:" << sizeof(Foo) << std::endl; std::cout << 
    "Fooplus is:" << sizeof(Fooplus) << std::endl; 
    
    return 0; 
    }
    

    we can see that Foo is rounded up to 4 bytes, but also that Fooplus packs in all the fields into 4 bytes:
    
    Foo is:4 Fooplus is:4
    


    The POWER architecture does provide for loads and stores of bytes, but integer operations are all on words (4 bytes). Typically, bit field structure members will have their values manipulated e.g. there will be adds, subtracts etc of these values. In these scenarios, it's ultimately faster to have these bit fields aligned on word boundaries so that the entire word can be loaded into a register and manipulated, probably with masks.

    While there will be scenarios where this approach costs a bit extra in space, such as the small test case you provided, we have found that on balance, optimizing for the manipulation of the bit fields is the better trade off.