Re: Delphi Type Narrowing

From: Bruce Roberts (ber_at_bounceitattcanada.xnet)
Date: 08/31/04


Date: Tue, 31 Aug 2004 11:42:43 -0400


"Ed" <contacted2001@yahoo.co.uk> wrote in message
news:22f4bce8.0408310429.30098769@posting.google.com...

> After wrestling with a bug on and off for over a week, I finally
> discovered that the programmer before me had mistakenly used the
> following:
>
> var
> TheData: TMemoryStream;
> DataOffset: Integer;
> .
> .
> TheData.Seek(soFromBeginning,DataOffset);
>
> when the seek signature is:
>
> function Seek(Offset: Longint; Origin: Word): Longint; override;
>
> Easy enough mistake to transpose the two parameters - much harder to
> spot that it had happend :-\ though. What I find rather disconcerting
> is that passing an integer as a parameter to a method that requires a
> word doesn't produce any compiler warnings or hints, much less a
> compile time error. IIRC in java any such type narrowing would
> require an explicit cast to allow compilation.
>
> Is this a missing feature in Delphi? Can anyone suggest a reason why
> this can happen e.g are there benefits from being able to do this or
> technical reasons why it must be so? I'm too tired and frustrated to
> think clearly about this and would greatly appreciate it if someone
> with more insight than myself could clarify this stuff.

Since the parameter is pass-by-value Delphi evaluates the expression, in
this case an integer, and then converts it to a word (in reality a straight
implicit typecast) to pass to the routine. The essential principal at work
here is Delphi's implicit type conversion rules when numeric expressions are
involved. Had the parameter been passed by reference (VAR) a compiler error
would have been generated since an expression isn't allowed.

Its a tough call. Without implicit numeric type conversion one would end up
having to type cast something as simple as "aDouble := 1;" (well one could
write aDouble := 1.0, but you know what I'm getting at).

Even with all compiler warnings and errors turned on the case you
encountered is never going to generate a compile or run-time message. After
all, all valid integer bit representations are also valid word bit
representations.

The correct solution, IMO, would have been a more proper definition of the
Seek method

    type tStreamSeekOffset = (soFromBeginning, soFromCurrent, soFromEnd);

    function Seek (Offset : LongInt; Origin : tStreamSeekOffset) : LongInt;

Unfortunately the VCL authors didn't do this.



Relevant Pages

  • Re: C# 3.0 Proposals
    ... Implicit means that it is assumed what the type is, ... Whereas with var, you can't do it, you will get a compiler error. ... "26.1 Implicitly typed local variables ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: How printf() works???????
    ... Getting something totally backwards is,of course, a mistake. ... is no evil intent in my correction. ... What he said to you about your compiler is beside the point and did not ... Therefore Robbie Hatley took your statement as correcting a ...
    (comp.lang.c)
  • Re: Ada exception block does NOT work?
    ... The parameter/formal declarations are like ... the compiler would guess for you how to call puts. ... > * implicit declaration of external functions. ... > K&R probably where good assember programmers but they where lousy compiler ...
    (comp.lang.ada)
  • Re: #define and (brackets)
    ... If I make a mistake, ... if the compiler knows enough to tell me ... due to some implicit type conversion say, then I define that conversion as ... That's automatic bug detection at compile time. ...
    (microsoft.public.vc.language)
  • Re: trim(string) problems
    ... >> Together these make me think it is a compiler problem ... >> but correctly finds size with both explicit and implicit ... that makes my test program with the module work and should ...
    (comp.lang.fortran)