Thanks, that clarifies the kind of problem you're thinking about. I think the primary difficulty of this argument is that I am viewing this as a yes/no proposition about whether to include a RAM wipe in the startup. It's not really an all-or-nothing issue, just it seemed initially phrased as one to me, and that reading felt dangerous to me. I'd like to clarify my priorities here:tokumaru wrote:I'm not opposed to clearing the RAM as an extra safety measure on your release build, but during development, it may give you the false sense of security that your modules are robust when they're actually not, if they neglect to initialize something that just happens to work if it starts out as 0, but fails with other values and you won't know it until you happen to re-run that module after that variable was left in a "bad" state.
Overall what I am adamantly opposed to is not setting RAM to a consistent state at startup on deployed code.
Whether or not you think it's safe to assume something is still 0 from the RAM wipe, that's a different issue. I think it's perfectly practical to do this carefully, but I can see how that can be a problem if you code in way that makes that error prone. If you want to initialize to $FF or $55 or change it infrequently during development to try and probe for accidental assumptions, I think that's a perfectly fine practice. Any consistent RAM state is fine for deployment, it doesn't have to be 0. I just happen to find 0 useful, but it's not what's important to me here at all.
I don't think randomizing it all the time while developing is the best way to approach that problem, though, because I think you should spend as much development time as you can testing with something as close to the deployment version as you can manage. So, from the premise that you must deploy this way, I think you should normally test this way too.
(Occasional smoke test sessions where you temporarily turn some part of the engine upside down and see if it still works are great to do, though.)
If you'll permit me to have a "koitsu" moment (please forgive me koitsu) I'd like to offer that the reason I have these priorities comes from my own personal experiences.
What I'm worried about is the "works on my machine" problem. If you don't initialize all of RAM, you'll now have a different startup environment on different emulators, on different flash cartridges, even on the same type of flash cartridge with different directory structures, etc. Deploying such a project to the world is inviting a nightmare of unreproducible errors. When I release a program and send it out to hundreds or thousands or people, difference-of-environment problems are the most frequent and most difficult thing I find myself dealing with, so they're at the very top of my list in terms of priority. It's really my number one deal, and it's why I say I feel strongly about this.
Here's one recent example of such a failure in deployment, but I can think of several others off the top of my head just on the NES alone. I've spent hundreds or maybe thousands of hours on these kinds of problems when releasing software (as both professional and amateur, on every single platform I've release software on), and they still fill me with fear.
On the other hand, I wipe RAM in all my NES programs and I can't think of a single time I've accidentally assumed something would be 0 in the wrong place (or if I have, it's still latent and nobody's noticed yet). I don't think I tend to have a lot of code that isn't clearly part of startup or not. Even when coding something like a main menu, I often use JMP $FFFC to return to the title screen if I can, instead of trying to rely on any assumptions about state since reset.
So... that's where my perspective is coming from. For me the "assumed 0 by accident" has been a non-issue, and the other one dominates the worst parts of my professional life, so if I'm weighing one against the other, there's no question to me which is the important one.
Outside of the NES, uninitialized variables is a big problem, especially in a language like C or C++ where guarantees about the environment are quite outside the language. There are some good tools for this, though-- modern C++ compilers can do static analysis and give you warnings about a lot of this kind of mistake. For some tougher ones there's great tools like Valgrind. In general I've learned the habit of initializing at declaration whenever it's not trivial (and leave a good comment if I really do want to leave it initialize). I'd love to see an NES debugger with some valgrindesque capabilities, though you can do a lot already with FCEUX + lua.