However, if you insist on coding that way, popping a 'asm volatile ("")' inside your loop will convince gcc at least to never optimise it away.
But do gcc or other compilers really optimise this things away?
In my reading of the standard this would definitely be non-conforming, have I overlooked something?
In the first case, if there are actually no statements with side effects inside the while ( "// stuff" ), the compiler could just assign 0 to delay and be done with that (since it's not been declared volatile), but cannot simply omit the loop, as its controlling expression has a visible side effect.
The second case is a bit hairier, but still it's not UB, and as such should be honoured. The compiler cannot assume it terminates and remove it as it has no side effects.