Read-only archive of the Armageddon Games Forums Archive (2000–2026) · About this archive

Compiler Bug: Weird loop behavior [b979]

8 replies · 1,775 views · Started 22 March 2009

Ok, I noticed that a function with a simple for loop was acting weird - basically the loop counter appeared to read from random memory. I found the problem - the loop counter variable was not declared within that scope. Instead of having the compiler issue an error - undeclared variable 'i' - it still compiled but seemed to use random memory.

For clarify here is the original function - truncated for space:


void RemoveRock(int idx)
{
if ( idx < Proj_RockCnt-1 )
{
for (i=idx; i<Proj_RockCnt-1; i++)
{
RockX[i] = RockX[i+1];
RockY[i] = RockY[i+1];
//...
}
}
Proj_RockCnt--;
}

Notice the problem? - 'i' is undeclared yet it still compiled.

If I simply add 'int i;' at the top of the function then it works as expected.

Definitely a bug, although I generally do my for-loops like this:

for(int i = 0; i < whatever; i++) {

The key being that I declare i right then and there.

I used to do that too - and sometimes still do. However you can run into compiler issues that way sometimes. For example using 'i' after the loop, such as


char szSomeString[32];
for (int i=0; i<n; i++)
{
szSomeString[i] = value;
}
szSomeString[i] = 0; // <-- NULL terminate string.

will work on some compilers and not others. Obviously it shouldn't work on any but... Then with multiple for loops at the same scope this can run into some "interesting" scope issues. I realize this isn't necessarily true for ZScript (I haven't tested it and don't have any loops that look like the above) - but it's a habit I have anyway to declare the loop counter outside the loop declaration.

Well, it depends on what you're iterating over, really. As far as i goes, I always use it (along with its cousins j, q and w) for throwaway loop counters, especially when I don't need to use it outside of the loop. So, by declaring it in the loop, I ensure that I can't use it outside of the loop.

(also, as a specific counter example to yours, you should fill the string with zeroes before hand. That way, you can't accidentally overflow the string)

Fair enough, we all have our own methods and reasons. 😊 And as you said, depending on what your counter is and what you're iterating over this can come up even with you methods. So its still important to fix this bug eventually. I'm clearly in the camp where I'd rather have an error or obvious crash then undefined behavior. I'm sure we can both agree on that.

All that said, I just tried something along the lines of:

for(int i = 0; i < 10; i++) {
for(j = 0; j < 4; j++) {
//stuff
}
}

And, the compiler errored at me, saying that j was undeclared.

So, please review your scripts, and make sure i isn't declared somewhere in a greater scope (eg, a global or something), since I can't verify this.

Well after searching the code... I did find the variable declared elsewhere. D'oh. It turns out it was declared in the proper scope for all other functions - which is why I didn't notice it before. In fact I'm not sure how it got declared outside a function, I did reorganize some code so I must have had a copy and paste error or something. A sloppy error nonetheless.

So if someone wants to remove this topic and file it under the "stupid" file, go ahead. Sorry about wasting your time, I'm usually more careful then this. 😡 I am glad I found the real problem though.

Next time I'll be more thorough before submitting something as a bug.

No worries... I'm actually a little disappointed, I was really scratching my head about how this bug could occur!

If you think something is a bug, even fi you're not toally sure, you should definitely post about it so that we're made aware of it. It's not really troublesome if it turns out to not be a bug.

Regardless, as this isn't a bug, it'll be moved out of this forum.