Being the perfectionist i am (all though it is not allways obvious) it illudes me how i could not have thought of this before.
I just ,ade a test which had the expected outcome:
Depends on what you mean. Yes, a bitfield takes less space than a series of bool, on average (because, on most machines, _Bool is merely a typedef to char or int). However, it is up to the implementation if your struct T1 does take one byte, two byte, four byte, or 5.67837 bytes of actual memory.
Every good solution is obvious once you've found it.
sizeof() will always return the size of the type. But bit field actual sizes and alignment are depended on implementation, so it would be unsafe to assume sizeof(T1) == 1. If you are assuming so, then add checks for this at the application startup. Just in case of the worst case scenario.
Trinka wrote:sizeof() will always return the size of the type. But bit field actual sizes and alignment are depended on implementation, so it would be unsafe to assume sizeof(T1) == 1. If you are assuming so, then add checks for this at the application startup. Just in case of the worst case scenario.
That was what i thought, but how else can it be tested?
then parse the return value in a shell script and #define a macro to it in config.h so you know the size in your actual program. Is there any other sort of testing you were thinking about?
The first step, the "configure" script, can be used to do the things jnc100 described: Trying things, and writing the results as #define statements in some header, so you can include that header in your code and act on the findings of the configure script.
Every good solution is obvious once you've found it.
If you are pedantic about it then you might also want to check that you actually get the performance benefit you are expecting. And, that you do not access the structure in any way such as casting it which would cause it to become non-portable like Solar and Trinka said.
A example is the compiling using GCC 3.4.4 or 4.1.2.
Trinka wrote:sizeof() will always return the size of the type. But bit field actual sizes and alignment are depended on implementation, so it would be unsafe to assume sizeof(T1) == 1. If you are assuming so, then add checks for this at the application startup.
// code hidden in some header
template <int a, int b> struct are_equal { enum { value = false }; };
template <int a> struct are_equal<a, a> { enum { value = true }; };
template <bool value> class assert_true;
template <> class assert_true<true> {};
// code in your program
static assert_true<are_equal<1, sizeof(struct T1)>::value> check_if_the_bitfield_works;
If your struct is 1, the value in the are_equal class define will be 1, the assert_true class will be defined (as shown above) and it will compile to a harmless unused global variable, which is optimized out entirely. If your struct is not 1 byte, it will be false, the class won't exist and you'll get a warning for an object with the name "check_if_the_bitfield_works" with the error that its class isn't defined.
Last edited by Candy on Tue Sep 18, 2007 2:32 pm, edited 1 time in total.
Trinka wrote:sizeof() will always return the size of the type. But bit field actual sizes and alignment are depended on implementation, so it would be unsafe to assume sizeof(T1) == 1. If you are assuming so, then add checks for this at the application startup.
// code hidden in some header
template <int a, int b> struct are_equal { enum { value = false; } };
template <int a> struct are_equal<a, a> { enum { value = true; } };
template <bool value> class assert_true;
template <> class assert_true<true> {};
// code in your program
static const assert_true<are_equal<1, sizeof(struct T1)>::value> check_if_the_bitfield_works;
If your struct is 1, the value in the are_equal class define will be 1, the assert_true class will be defined (as shown above) and it will compile to a harmless unused global variable, which is optimized out entirely. If your struct is not 1 byte, it will be false, the class won't exist and you'll get a warning for an object with the name "check_if_the_bitfield_works" with the error that its class isn't defined.
Have you tested this code? I think maybe a couble of ';'s are missing after the enum declarations, but even with that fixed i cant get it to work.
Zacariaz wrote:Have you tested this code? I think maybe a couble of ';'s are missing after the enum declarations, but even with that fixed i cant get it to work.
As usual, I don't test my submissions. The theory is more important to understand than the copy-paste.
Sec.
Move the semicolons from after true and false to after the }, remove const from the definition (since it's static anyway, it'll be optimized away anyway).
Trinka wrote:sizeof() will always return the size of the type. But bit field actual sizes and alignment are depended on implementation, so it would be unsafe to assume sizeof(T1) == 1. If you are assuming so, then add checks for this at the application startup.
// code hidden in some header
template <int a, int b> struct are_equal { enum { value = false }; };
template <int a> struct are_equal<a, a> { enum { value = true }; };
template <bool value> class assert_true;
template <> class assert_true<true> {};
// code in your program
static assert_true<are_equal<1, sizeof(struct T1)>::value> check_if_the_bitfield_works;
If your struct is 1, the value in the are_equal class define will be 1, the assert_true class will be defined (as shown above) and it will compile to a harmless unused global variable, which is optimized out entirely. If your struct is not 1 byte, it will be false, the class won't exist and you'll get a warning for an object with the name "check_if_the_bitfield_works" with the error that its class isn't defined.
Nice! I always wondered if it's possible to test the sizeof() during compile time instead of runtime. Thanks!