In some compilers, to "merge" the bits, all items must be of the same type. So make it uint32_t
where you now have uint8_t
- this appears to not be the case in the compiler IdeOne uses tho'
[No matter what, It is still up to the compiler how it merges the bits, so it the only way to absolutely guarantee that your data is stored as 32 bits is to use a single uint32_t
and declare a class that does the relevant shifting and anding/oring to manipulate the value - the only guarantee you have is that ONE element in your struct will have at least as many bits as you have asked for]
As others have pointed out, you can't start a new structure on other than a byte boundary. I fixed it by having a second struct inside the union, like this:
http://ideone.com/Mr1gjD
#include <stdint.h>
#include <stdio.h>
typedef struct structTag {
union {
struct {
uint32_t messageID : 26; /* 26bit message id, 67108864 ids */
uint8_t priority : 3; /* priority: MUST BE 0 */
} __attribute__ ((packed));
struct {
uint32_t rawID : 29;
uint8_t canFlags : 3;
};
} __attribute__ ((packed));
} __attribute__ ((packed)) idSpecial;
int main() {
printf("size: %d", sizeof(idSpecial));
return 0;
}