LED blinking while loop not working AVR timer 0
By NOT declaring it volatile you give the compiler permission to optimise. 

In the first loop, the compiler knows the value of C at all times, because nothing else in the loop can modify C (and it isn't volatile) so, because C is always 0, the loop doesn't need to do anything. The code is working perfectly because that's what you asked for.

In the second loop, you call a procedure (oops, void function) NOP() which could do absolutely anything. So, unless the compiler does whole program analysis over all the libraries (and it doesn't), how does it know if NOP() modifies C?

It doesn't, so it can't make any assumptions about C's value and has to re-fetch it from memory.

Ths second program isn't working, it does what you expect by accident. 

If the "random additional line" didn't involve a call - e.g. it was an inline assembly NOP instruction, you would probably see different behaviour.

Declare C volatile.