delaying execution with an empty loop doesn't work?

I am not sure if it counts as a programming problem, or if it is something more general, but here it goes:

I need to delay execution of the program. delay(1) works, but the delay is too long. I can't use delayMicroseconds() as I am targetting ATtiny13 (but I have reproduced the problem on Arduino Uno). I tried to use just an empty loop:

void wait(unsigned int t)
{
  while (t--);
}

and it didn't work at all, as if the code was ignored. After some digging I have found library function _delay_loop_2(), which technically does exactly the same thing - executes an empty loop - but it is written in assembly, and works:

void
_delay_loop_2(uint16_t __count)
{
	__asm__ volatile (
		"1: sbiw %0,1" "\n\t"
		"brne 1b"
		: "=w" (__count)
		: "0" (__count)
	);
}

Any idea why that's the case? Why my wait() function doesn't work? The only thing I can think of is that it is an effect of compiler optimization - it ignores the code that does nothing. Is that the case? And if so - do I guess correctly that there should exist some #pragmas to switch the optimization locally off? (Never used gcc, I am rather a Microsoft/Visual compilers guy).

Hi,
Use an empty "for" loop.

Tom.. :slight_smile:

...with a volatile control variable

Compilers optimize code. Here the variable t is never used after the loop and thus the compiler
correctly deduces that the loop has no side-effects and can be deleted. If you had returned t that
might be enough to defeat the optimization.

A way to guarantee that the loop isn't optimized away is to make t global and volatile, so the compiler
isn't allowed to discard any uses or definitions of a volatile - google data-flow analysis for more information
on compiler optimizations like this.

OK, thanks, looks like I was on the right track.

Just one comment: global variable is probably out of the question, that goes against rules for size optimization spelled out in AVR4027 (my code still fits ATtiny13's 64 bytes/1k, but I don't have many bytes to spare).