overflow/range error not detected by delphi

overflow/range error not detected by delphi

I had code as follows:
Q.ParamByName('iID').AsInteger := lNextID;

lNextID is defined as Int64, but I used the AsInteger (which is type
Integer - ie 32-bits large), but even with Overflow and Range Checking
enabled (and a total project rebuild), Delphi never complained or hinted that I made a mistake or that data could be truncated. Weird??

Subsequently I changed the code to .AsLargeInt := lNextID;

I'm using Delphi 10.2.2 and it's a 32-bit Windows project.

Comments

  1. Delphi type "system" is an ad hoc year-by-year mix of safe and fast, rigorous and permissive bag of artifacts with little unifying idea, if any. You just have to memorize things.


    It is not hard to explain in retrospect, though. Due to performance reasons of 1980-s it was always so for Int8 (byte) and Int16(integer) in the original Turbo Pascal years. LongInt back then internally was a set of TWO int16 vars. With Delphi 2.0 the native integer type was extended to Int32, but behavior remained. Both to keep source-level compatibility and to avoid re-writing the already working compiler parts. With Delphi XE2 the native integer type was extended yet again (for Win64 platform), now to Int64. but the behavior was kept for the same reasons: compatibility with the vast body of already written code plus performance.

    So, if you dig a bit into the history you may quite expect it. And in retrospect it is clear and obvious.
    Or you can just memorize things.

    ReplyDelete
  2. Delphi never checked between conversions of integer types (Integer, Longint and Int64 are all integer types). Can you imagine how many hints you would get? The whole source is riddled with integer conversions. AsInteger is actually a LongInt in IBX (and I expect in other Datasets too). Also see stackoverflow.com - Delphi compile-time integer conversion warnings?

    ReplyDelete
  3. Thanks for the info. Following the link provided and reading the comments, it seems most developers would prefer an option in Delphi to actually tell you about such issues at compile time. It seems like quite a logical thing to expect. Yet more feature requests by actual developers going unheard by EMBT, and instead we get given more useless IDE themes and such.

    ReplyDelete
  4. There is a range check happening but it depends on what is in the int64. If that fits into an int32 everything is fine, otherwise you get a range error.

    See this code:

    var
    i: Integer;
    i2: Int64;
    begin
    {$RANGECHECKS ON}
    i2 := High(Integer);
    i := i2;
    Writeln(i);
    Inc(i2);
    i := i2; // <- boom
    Writeln(i);
    end.

    FWIW: FPC also does not give any hint at compiletime - see http://forum.lazarus-ide.org/index.php?topic=42568.0

    ReplyDelete
  5. Stefan Glienke : Unfortunately, you are wrong regarding your FPC comment. FPC has support for warning the developer of such mistakes. Simply add the dedicated -CO compiler parameter. Here it shows the compiler warning:

    $ fpc -CO -vh overflow.pas
    Hint: Start of reading config file /home/graemeg/.fpc.cfg
    Hint: End of reading config file /home/graemeg/.fpc.cfg
    Free Pascal Compiler version 3.0.4+dfsg-18ubuntu2 [2018/08/29] for x86_64
    Copyright (c) 1993-2017 by Florian Klaempfl and others
    Target OS: Linux for x86-64
    Compiling overflow.pas
    overflow.pas(11,7) Hint: Type size mismatch, possible loss of data / range check error
    Linking overflow
    /usr/bin/ld.bfd: warning: link.res contains output sections; did you forget -T?
    14 lines compiled, 0.0 sec
    3 hint(s) issued

    ReplyDelete
  6. Graeme Geldenhuys Interesting, now please also tell the people on the Lazarus forums - they might be more interested than me ;)

    ReplyDelete
  7. Will do, I just didn't want more false information spread. Fake news and all. ;-)

    ReplyDelete
  8. In Go there are no implicit conversions between numeric types. I would welcome this feature in the Delphi compiler.

    tour.golang.org - A Tour of Go

    ReplyDelete
  9. Maybe advanced records can be used to inhibit comversions?

    There was some lib, that used A.R. to move back Extended (10 bytes x87 floating point) into Delphi Win64 compiler

    ReplyDelete

Post a Comment