syntax

I wanted to have an array index cycle 0,1,2,3,0,1,2,3,0...

I wrote what looks good to me, but it kept incrementing wrote off the end of the array, eventually clobbering millis and who knows what else. I rewrote it as two separate lines and it works. Still not understanding what went wrong-and feeling like I was going to be superstitious about wierd goings-on unless I understood it, I fired up Arduino 17 and boiled the lines down to the minimal case. the optimizer realized nothing was really being done so I made the variable volatile. When I read this, it looks to me like the compiler is ignoring my parentheses. What is really going on?

volatile uint8_t updateIndex;
void loop (void){
  updateIndex = 0x03 & (updateIndex++); //this is buggy
 12c:      80 91 00 02       lds      r24, 0x0200
 130:      98 2f             mov      r25, r24
 132:      93 70             andi      r25, 0x03      ; 3      //SO THE AND IS DONE FIRST
 134:      90 93 00 02       sts      0x0200, r25
 138:      8f 5f             subi      r24, 0xFF      ; 255
 13a:      80 93 00 02       sts      0x0200, r24
  
    //
    updateIndex++;
 13e:      80 91 00 02       lds      r24, 0x0200
 142:      8f 5f             subi      r24, 0xFF      ; 255
 144:      80 93 00 02       sts      0x0200, r24
    updateIndex &= 0x03;     //this works
 148:      80 91 00 02       lds      r24, 0x0200
 14c:      83 70             andi      r24, 0x03      ; 3   //HERE THE AND IS DONE 2ND :-/
 14e:      80 93 00 02       sts      0x0200, r24
 152:      ec cf             rjmp      .-40           ; 0x12c <main+0x4>

:-?

I would change this:

updateIndex = 0x03 & (updateIndex++); //this is buggy

to this:

++updateIndex &= 0x03;

The key here is using pre increment rather than post increment. You could also write this on two separate lines:

  updateIndex++;
  updateIndex &= 0x03;

or if you prefer:

  updateIndex++;
  updateIndex = updateIndex & 0x03;

All versions will compile to the exact same assembly code so the choice is one of style/readability/preference rather than performance.

I like your first option although it would never have occurred to me!
The second option is exactly what I did write (and it probably would compile to exactly the same thing if I hadn't done the volatile thing after I oversimplified).

actually looking at my first post a little closer, it ANDs r25, stores that, then overwrites it from r24.