you COULD confirm proper behavior by inspecting the assembly language produced. If the "volatile" is working, then a code segment like:
x.b = 1;
if (x.b == 0)
Serial.print("ta da");
should produce something like:
ldi r24, 1 ;; get a 1
sts r24, 0x1234 ;; store it in the memory location for x.b
lds t24, 0x1234 ;; get the value in the memory location for x.b
cpi r24, 1 ;; compare
But without "volatile" (or if it doesn't work), the "lds" instruction would be omitted since the compiler clearly knows that r24 still has that variable's value. (probably the whole if statement would get omitted in this case, since it's clearly false...)
Could examine the assembly but is does not correspond to GTL!
There are 14 registers, R0-R13, all are created equal, but convention dictates how some are used!
struct {
int a;
volatile int b;
} x;
void setup() {
// put your setup code here, to run once:
x.a = 1;
if (x.a == 0) {
Serial.print("x.a magically zero.");
}
x.b = 1;
if (x.b == 0) {
Serial.print("x.b magically zero.");
}
}
I get
80128: 4b05 ldr r3, [pc, #20] ; get data area pointer.
8012a: 2201 movs r2, #1 ; get constant 1
8012c: 605a str r2, [r3, #4] ;store 1 in x.b
8012e: 601a str r2, [r3, #0] ; and also in x.a
; here we'd compare x.a for zero, but the compile knows it's not
; so it just omitted all that code.
80130: 685b ldr r3, [r3, #4] ; read x.b again! Because it's volatile!
80132: b91b cbnz r3, 8013c <setup+0x14> ; test and jump from 'if'
80134: 4803 ldr r0, [pc, #12] ; get string
80136: 4904 ldr r1, [pc, #16] ; Another arg for "print" ?
80138: f000 b89b b.w 80272 <_ZN5Print5printEPKc> ; print it
8013c: 4770 bx lr ; "return" instruction at end of setup()
8013e: bf00 nop ; branch delay slot.