compiler bug of vc71?

G

Gabest

I've got a little problem with the following few lines of code (copypasted
from the stopped debugger):

int extra1 = max((int)h->size - sizeof(OggStreamHeader), 0);

0148FA42 mov eax,dword ptr [h]
0148FA45 mov ecx,dword ptr [eax+0Ch]
0148FA48 sub ecx,38h
0148FA4B je COggVideoOutputPin::COggVideoOutputPin+0AEh (148FA5Eh)
0148FA4D mov edx,dword ptr [h]
0148FA50 mov eax,dword ptr [edx+0Ch]
0148FA53 sub eax,38h
0148FA56 mov dword ptr [ebp-198h],eax
0148FA5C jmp COggVideoOutputPin::COggVideoOutputPin+0B8h (148FA68h)
0148FA5E mov dword ptr [ebp-198h],0
0148FA68 mov ecx,dword ptr [ebp-198h]
0148FA6E mov dword ptr [extra1],ecx

int extra2 = (int)h->size - sizeof(OggStreamHeader);

0148FA71 mov eax,dword ptr [h]
0148FA74 mov ecx,dword ptr [eax+0Ch]
0148FA77 sub ecx,38h
0148FA7A mov dword ptr [extra2],ecx

extra2 = max(extra2, 0);

0148FA7D xor eax,eax
0148FA7F cmp dword ptr [extra2],0
0148FA83 setle al
0148FA86 dec eax
0148FA87 and eax,dword ptr [extra2]
0148FA8A mov dword ptr [extra2],eax

-----------

It's very simple to describe, extra1 becomes -4 (wrong), extra2 becomes 0
(correct). Yes, I know the first solution has some overhead, but it is very
easy to code this way because of laziness..., and it can't be a reason for
the compiler to produce wrong code either :) The question is, why can't we
see any sign of less or equal comparison in the first assembly listing? Only
one "je" is there. (btw, the compiler used a really nice trick in the second
case, considering it was just the debug build :)
 
G

Gabest

Gabest said:
I've got a little problem with the following few lines of code (copypasted
from the stopped debugger):

int extra1 = max((int)h->size - sizeof(OggStreamHeader), 0);

Doh, can it be that (int)h->size - sizeof(OggStreamHeader) becomes unsigned
again? Is there any rule for such cases, like the last or "wider" decides
the type?
 
C

Carl Daniel [VC++ MVP]

Gabest said:
It's very simple to describe, extra1 becomes -4 (wrong), extra2
becomes 0 (correct).

The result of the subtraction has the type 'unsigned int', while the literal
0 has the type 'int'. Applying the max macro to values of different types
has (I believe) unspecified behavior.
Yes, I know the first solution has some
overhead, but it is very easy to code this way because of
laziness..., and it can't be a reason for the compiler to produce
wrong code either :) The question is, why can't we see any sign of
less or equal comparison in the first assembly listing? Only one "je"
is there. (btw, the compiler used a really nice trick in the second
case, considering it was just the debug build :)

There's no relational operator because the type of the operands is
unsigned - the only unsigned number that's not greater than zero is zero
itself.

-cd
 

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