Search code examples
cstructbit-fields

Will the size of bitfield be saved even if assigment is via pointer?


Let's assume I have

struct foo
{
unsigned int bar : 7;
unsigned int next_field : 1;
}
void funct()
{
struct foo demo;
demo.next_field = 0;
unsigned char *barptr  = (unsigned char *)&demo;
/*1 = 00000001, bar can contain only 7 bits*/
*barptr = 1;
}

since bar is 7 bit where as char is 8 bits, what will happen? Will bar be filled with zeros and next_field contain the 1? Will the result be:

0000000  1
|_____| |_|
  bar

or

0000001  0
|_____| |_|
  bar

or:

0000000  0
|_____| |_|
  bar

I would check using my compiler but I don't know wether this behavior is implementation-defined, in witch case the compiler can be misleading.


Solution

  • At this point you are quite brutally crossing borders of clean programming.

    unsigned char *barptr  = &foo.bar; /* first version of the question */
    unsigned char *barptr  = (unsigned char *)&demo; /* after edit  */
    

    You are using the address of something which is not a char in at least two ways and write it to a pointer to char.

    After that using that pointer basically tells the compiler "Here is a char. Honest. Believe me. Trust me. Just write it." Whether or not you do that with a type cast (one of the differences between the two versions) is actually irrelevant.

    *barptr = 1;
    

    Any "knowing bitsize of bitfield" which the compiler had before have been flattened by you blatantly lying to the compiler afterwards.

    If you want to cleanly write bar via a pointer do it like this

    struct foo *demop;
    demop = &demo;
    demop->bar = 1;