0

The below algorithm can output 99 0000

Would you please let me know how does this following line of code work?

*(long*)&(st->flag1) = 0;

The algorithm is:

#include <stdio.h>

struct SpecialFlags{
 int  id;
 char flag1;
 char flag2;
 char flag3;
 char flag4;
};


void ClearFlags( SpecialFlags *st )
{
  *(long*)&(st->flag1) = 0;
}

int main(void)
{
  SpecialFlags flags;
  flags.id =    99;

  flags.flag1 = 1;
  flags.flag2 = 2;
  flags.flag3 = 3;
  flags.flag4 = 4;
  ClearFlags( &flags );

  printf( "%d %d%d%d%d\n", flags.id, 
    flags.flag1, flags.flag2, 
    flags.flag3, flags.flag4 );
  return 0;
}
11
  • 11
    It drives the last nail into the undefined coffin. Commented Feb 21, 2018 at 14:07
  • Read from right to left. Take the address (&) of st->flag1, cast it to a long*, and then dereference (*) that pointer. Whoever wrote that is using it as a terrible hack to set all four flags to 0. Commented Feb 21, 2018 at 14:09
  • @0x5453 & here takes the address of, not reference Commented Feb 21, 2018 at 14:10
  • ...**if** sizeof long actually is 4... Commented Feb 21, 2018 at 14:12
  • 1
    @DevSolar I missed the if in your comment. Commented Feb 21, 2018 at 16:49

1 Answer 1

0

In the Below structure

struct SpecialFlags{
        int  id;
        char flag1;
        char flag2;
        char flag3;
        char flag4;
};

        id       flag1     flag2     flag3      flag4
     -------------------------------------------------- 
     | 99      | 1(49)    | 2(50)   | 3(51)   |  4(52) |
     ---------------------------------------------------
   0x100     0x104       0x105     0x106      0x107   0x108 <--lets say starting address is 0x100

When ClearFlags() is called st points to beginning of the structure. And when you do *(long*)&(st->flag1) = 0; First address of st->flags1(char type) gets converted to long* type that means it will fetch 4 bytes at a time and finally * means value in that 4 bytes.

From above figure

  • (long*)&(st->flag1) => from 0x104 address till next 4 byte i.e till 0x108
  • *(long*)&(st->flag1) => what value is there in between 0x104 location to 0x108 location
  • *(long*)&(st->flag1) = 0 => what value is there in between 0x104 location to 0x108 location, will be overwritten with 0(zero)

After this statement your structure looks like

       id       flag1     flag2     flag3      flag4
     -------------------------------------------------- 
     | 99      | 0(48)    | 0(48)   | 0(48)   |  0(48) |
     ---------------------------------------------------
   0x100     0x104       0x105     0x106      0x107   0x108

Now when you prints flags.flag1, flags.flag2.. it prints 0.

Sign up to request clarification or add additional context in comments.

1 Comment

There is a small mistake. The values are numbers and not chars. So 0 is 0 and not 48. If you want to set the flags to '0', you need to assign *(long*)&(st->flag1) = 48+256*(48+256*(48+256*48));

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.