Debug vs Release Behavior in VC ++ 6.0

In the program below, I get different results depending on whether I run it in Debug or Release mode in VC ++ 6.0 on Windows 7. Differences in Debug and Release behavior almost always indicate errors in handling pointers and loops, but I I cannot indicate an error.

In debug mode, I get the expected results:

Entered loop with i == 0, RecordCountNew == 0
RecordCountNew = 1 is positive.
Entered loop with i == 1, RecordCountNew == 1
Adding record with i == 1, RecordCountNew == 1
Added record with i == 1, RecordCountNew == 2
RecordCountNew = 3 is positive.
Entered loop with i == 2, RecordCountNew == 3
RecordCountNew = 4 is positive.
Finished loop with i == 3, RecordCountNew == 4

      

In Release mode, I get the same results except for the statement that RecordCountNew is positive:

Entered loop with i == 0, RecordCountNew == 0
RecordCountNew = 1 is positive.
Entered loop with i == 1, RecordCountNew == 1
Adding record with i == 1, RecordCountNew == 1
Added record with i == 1, RecordCountNew == 2
RecordCountNew = 3 is positive.
Entered loop with i == 2, RecordCountNew == 3
Finished loop with i == 3, RecordCountNew == 4

      

Can anyone replicate this on their machine, or better yet, explain it?

#include <stdio.h>
#include <algorithm>

using namespace std;

struct record {
    int ID;
};

int RecordLimit;
record* Records = NULL;
record** RecordIndex = NULL;
record** RecordIndexNew = NULL;

int main(int argc, char* argv[]) {

    RecordLimit = 10;
    Records = new (nothrow) record[RecordLimit];
    RecordIndex = new (nothrow) record*[RecordLimit];
    RecordIndexNew = new (nothrow) record*[RecordLimit];

    int i;
    for (i = 0; i < RecordLimit; i++) {
        RecordIndex[i] = NULL;
        RecordIndexNew[i] = NULL;
    }

    int RecordCount = 0;
    for (i = 0; i < 3; i++) {
        Records[i].ID = i;
        RecordCount++;
    }

    int RecordCountNew = 0;
    for (i = 0; i < RecordCount; i++) {

        printf("Entered loop with i == %d, RecordCountNew == %d\n", i, RecordCountNew);

        RecordIndexNew[RecordCountNew] = RecordIndex[i];

        bool AddNewRecord = (i == 1);

        if (AddNewRecord) {
            printf("Adding record with i == %d, RecordCountNew == %d\n", i, RecordCountNew);
            Records[RecordCount + (RecordCountNew - i)].ID = RecordCount + (RecordCountNew - i);
            RecordIndexNew[RecordCountNew + 1] = RecordIndexNew[RecordCountNew];
            RecordIndexNew[RecordCountNew] = &Records[RecordCount + (RecordCountNew - i)];
            RecordCountNew++;
            printf("Added record with i == %d, RecordCountNew == %d\n", i, RecordCountNew);
        }

        RecordCountNew++;
        if (RecordCountNew > 0) printf("RecordCountNew == %d is positive.\n", RecordCountNew);
    }

    printf("Finished loop with i == %d, RecordCountNew == %d\n", i, RecordCountNew);

    delete[] Records;
    delete[] RecordIndex;
    delete[] RecordIndexNew;

    return 0;
}

      

+3


source to share


1 answer


(Correction replaces previous comment): Similar results in VC6 ++ SP6, but I don't get any positive results at all. I'll see. Let's see if I can find anything. No promises (Euro Micelli)

I replicated the same results (didn't pop up at all on Release) found by @EuroMicelli. However, if you declare RecordCountNew

as volatile, the outputs are present:

volatile int RecordCountNew = 0;

      

For your information, volatile is a keyword that tells the compiler that a variable can be changed externally at an arbitrary time (such as when the processor is interrupted) and prevents the compiler from aggressively optimizing the code around it.

TL; DR : MSVC6

Incorrectly optimized RecordCountNew

.

PS: declaring RecordCountNew

like short

instead int

will cause the print results to be re-displayed. You never know what's going on in the brain of a 20 year old compiler.



PPS: Since I am asked to explain the error, here is a parsed version of the correct output:

enter image description here

register will edi

store the value RecordCountNew

and command of the command test

to jump to printf

. However, here's the compiled version of the OP:

enter image description here

The condition test

is executed in the base pointer register ebp

, which has nothing to do with RecordCountNew

. Depending on the value, the ebp

program outputs the string every time or never.

+2


source







All Articles