[fpc-devel] bug: Inc(v,i)/Dec(v,i)

Marcel Martin mm10 at ellipsa.net
Sun Jul 10 01:14:09 CEST 2005


Hans-Peter Diettrich a écrit :
> Peter Vreman wrote:
> 
> 
>>>IMO the compiler can convert between Inc and Dec, for negative
>>>constants, so that the value always is positive, compatible with
>>>signed and unsigned data types.
>>
>>That means different behaviour between the use of a variable or constant.
>>That is something you never want.
> 
> 
> Why not? I expect that the compiler evaluates constant expressions, and
> creates the best code for the resulting values.

The best code is, before all, the correct code.

>>>>So, if x is a Longword and if SomeConstant equals
>>>>-1, either it adds $ffffffff (and there will be an overflow
>>>>if x > 0) or it stops at compile time saying that -1 is not
>>>>a Longword.
> 
> 
> In the case of Inc(x, SomeConstant) the value of the named constant can
> be changed, with arbitrary positive or negative values. Would you then
> want to find all uses of "someconst" in your code, to find out where
> your code deserves a modification?

If I declare a constant as an unsigned integer, if I wrote my
code assuming it is an unsigned integer and if, suddenly,
I decide to change that, of course, I may expect some problems.

Note: I have the feeling that you are confusing signed/unsigned
and negative/positive. When I talk of unsigned integers, I am not
talking about signed ones that may be positive. No, I am talking
about integers that can never be negative.

> IMO every calculation, that can result in illegal results in *normal*
> operation, has to be handled appropriately in the code. If no problems
> are predicted, expected, and handled, in explicit code, the compiler
> only has to care about coding errors, that result in *unexpected*
> overflows. I don't think that a calculation should produce or not
> produce an overflow, depending only on the sign of the given value.

Unexpected overflows? The overflows occur or not according to
simple rules, perfectly defined, which ones depend on the types
of the operands.
If A is a Longword (this is an unsigned type, no instance can be
negative). So if A = 2^32-1 and if I compute A + 1, there is an
overflow because the resulting value should be 2^32 and this value
doesn't exist for the Longword type.

 > From
> the mathematical viewpoint +(+1) and -(-1) is perfectly equivalent, as
> is +(-1) and -(+1). 

Computationally, this is not equivalent.
+(-1) -> add eax, $ffffffff
-(+1) -> sub eax, $00000001
And at this point, even if we know the content of eax before the
operation, we cannot know if there is or not an overflow without
knowing the type of the integer contained in eax.

Moreover, when programming, mathematical considerations have to
be handled with care. Mathematically, (x = -x) -> (x = 0).
Computationally, this is wrong (because the computer doesn't work
over the ring Z but over a ring Z/2^kZ). If x is a Longint and
if x = -x, either x = 0 or x = -2^31.
Try this

   x : Longint;
   ...
   x := Longint($80000000); // x := -2^31
   WriteLn(IntToStr(x));
   x := -x;
   WriteLn(IntToStr(x));

(And this is not a bug. This is a consequence of the 2-complement
representation of signed integers.)

 > When there exist reasons why such expressions should
> be handled differently, the user is responsible for indicating such an
> exceptional situation.

If the situation is such that I want no overflows, I always can
tell the compiler: {$Q-}.

mm




More information about the fpc-devel mailing list