Compiler generated code bug in Debug build

J

Jan Bares

Hi,

I have found a bug in generated code in debug build. I have Visual C++ .NET
7.1.3088. Function Buggy::isBug() returns true and it should return false.
The sample is contrived to exhibit the bug in small code. The expression

m_array + sizeof(Buggy) * m_used

is actualy compiled as

m_array + sizeof(Buggy) * sizeof(Buggy) * m_used

If you look into assembly you should see something like this:

00411276 mov eax,dword ptr [this]
00411279 mov ecx,dword ptr [eax+1F8h]
0041127F imul ecx,ecx,1FCh
00411285 imul ecx,ecx,1FCh // <<<<<<<< ????
0041128B mov edx,dword ptr [this]
0041128E add ecx,dword ptr [edx+1F4h]


Thanks for any feedback, Jan


The sample code
===============
struct Buggy
{
char ch[500];// must be bigger otherwise shl will be used instead of imul
Buggy* m_array;
int m_used;

bool isBug()
{
m_array = 0;
m_used = 1;

return sizeof(Buggy) != int(m_array + sizeof(Buggy) * m_used);
}
};

int main()
{
Buggy test;

test.isBug();

return 0;
}
 
C

Carl Daniel [VC++ MVP]

Jan said:
Hi,

I have found a bug in generated code in debug build. I have Visual
C++ .NET

Actually, you haven't. See below for the source of your misunderstanding.
7.1.3088. Function Buggy::isBug() returns true and it should return
false. The sample is contrived to exhibit the bug in small code. The
expression

m_array + sizeof(Buggy) * m_used

is actualy compiled as

m_array + sizeof(Buggy) * sizeof(Buggy) * m_used

Actually, it's not.
If you look into assembly you should see something like this:

00411276 mov eax,dword ptr [this]
00411279 mov ecx,dword ptr [eax+1F8h]
0041127F imul ecx,ecx,1FCh
00411285 imul ecx,ecx,1FCh // <<<<<<<< ????
0041128B mov edx,dword ptr [this]
0041128E add ecx,dword ptr [edx+1F4h]


Thanks for any feedback, Jan


The sample code
===============
struct Buggy
{
char ch[500];
Buggy* m_array;
int m_used;

bool isBug()
{
m_array = 0;
m_used = 1;

return sizeof(Buggy) != int(m_array + sizeof(Buggy) * m_used);

The compiler is doing exactly what you told it. m_array is of type Buggy*.
m_array+sizeof(Buggy) is also of type Buggy* - its value is computed by
multiplying (*m_array) by sizeof(Buggy) and then adding the result to
m_array. Remember, you're doing pointer math here. The compiler correctly
observed that m_used==1 and didn't emit any code to perform that
calculation.

Presumably you meant to write:

return sizeof(Buggy) != int(m_array) + sizeof(Buggy) * m_used;

.... or something like that. It's not clear what this code is supposed to
do, but then you did say it's contrived.
}
};

int main()
{
Buggy test;

test.isBug();

return 0;
}

If you still have problems with some uncontrived code, please post again.

-cd
 
J

Jan Bares

Thanks Carl, I just realized that and wanted to disregard this stupidity, I
must be off my brain.

Jan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top