I've got a function that initialises a large array, that goes like so:
m_array[i++] = ArrayItem(1, 2, 3, "blah");
m_array[i++] = ArrayItem(9, 16, 3, "foo");
m_array[i++] = ArrayItem(0xdead, 0xcafe, 0xbabe, "beef");
And so on. Each ArrayItem is about 128 bytes, and there's 70-odd entries. After I spent an hour or two crawling through ARM9 assembly code and CodeWarrior symbol files tracking down some obscure memory corruption bugs, the technical director suggested that we might be running out of stack. So, we took a look at the stack pointer and found that CodeWarrior had decided not to allocate one temporary variable that was re-used (As I know Visual Studio does), but to allocate stack space for 70 of them, and to fill in each one, then copy the contents over. 70 times 128 bytes is over 8K, which is way over the total stack size available. The DS CPU doesn't do any exceptions or anything and just lets you carry on writing past the end of the stack and into random memory.
First of all, I didn't expect CodeWarrior to allocate 70 of the damn things, but my main concern is the way it allocated any at all. The struct only contains POD types; 3 ints and a char buffer. There's en empty default constructor, and no copy constructor or anything like that, so the optimiser should have been able to directly initialise the array given the values passed to the struct instead of allocating a struct, filling it in, then copying the data out.
And yes, this is an optimised build.
The fix was to change the construct-and-assign method to a function call; set(), which now uses 16 bytes of stack. Much better. And a fraction of the code size too.
So I'm now very wary of assuming CodeWarrior will do any sort of optimisation that Visual Studio does without thinking about it.