I spent about 2 hours last night pounding my head in a wall trying to figure out the solution to a new bug that I ran into: Anguna's save game function was no longer working.
In the GBA, the most common save method is to just write to a magical area of ram that happens to be battery-backed, so it retains its values. So when I save, I write the game state to that area, including a checksum. On loading, I read the checksum to see if there's a valid game state in ram (as opposed to un-initialized garbage), and if it's valid, load it.
So last night, I was writing the data, but then when I read it back out, the checksums didn't match!
So I started debugging. I logged the first few bytes writing to save, and logged them again as I read them...everything looked right. So the first few bytes were working. I tried again with the last few bytes -- they matched also. Weird.
So I dumped ALL the data to a log upon saving and loading. And Lo And Behold, they matched, and it worked correctly. Uh oh.
I removed the debugging, and it broke again.
This is normally an unhappy position to be, although this time it quickly led me to the solution. There were no actual side effects of my logging code (other than the logging itself), so clearly the compiler was optimizing something differently.
Then I checked to make sure that the save ram was marked as volatile. Nope. Oops.
In C, you can mark variables/memory/etc as volatile, which means that its value can be read or written outside of your current program. This lets the compiler know NOT to optimize away read/writes to it.
For example, in the gba, to get the state of the controller inputs, you read a particular memory location. If you don't mark it as volatile, the compiler will notice that you are reading it every frame, but never writing to it, and might optimize away your other reads. Which is not what you want.
In this case, I'm not sure exactly WHAT the compiler was thinking in optimizing away my reads/writes to the save data, but marking it as volatile did the trick. And I guess the compiler's optimization strategies have changed since I last worked on Anguna, as I never had it marked volatile before. Oh well.