Typecasting by accident

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Typecasting by accident

Vinzent Höfler
Just found a bug of mine I was wondering about since about three days,
and wanted to share the fun with you:

-- 8< --

// "How to raise the wrong exception" or
// "Why automatic type conversion really sucks"

{$MODE OBJFPC}

program
   Exception_Fun;


uses
   SysUtils;


function Exception_Message : AnsiString;
begin
   exit ('Will never show up, of course.');
end {Exception_Message};

type
   Not_Now = class (SysUtils.Exception);

begin
   try
      raise Not_Now (Exception_Message);
   except
      on e : Not_Now do
         WriteLn (StdErr, 'Caught it! Strange.');
   end {try};
end {Exception_Fun}.

-- 8< --

No error, no warning, no note, no hint: Of course, a class type is just
a pointer, AnsiStrings can be pointers. Pointers can be converted to
any other pointer type... *crash*

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Typecasting by accident

Matt Emson

>       raise Not_Now (Exception_Message);

I feel your pain!

far too much like :

throw Not_Now(Exception_Message);

My brain does this all the time moving between C# and Delphi. The one I
always seem to do, is "except" instead of "catch" in "try" blocks. At
least the compiler/syntax checker gets that one right away ;-)


M

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Typecasting by accident

etrusco
In reply to this post by Vinzent Höfler
Weird, I wouldn't expect OBJFPC mode to allow automatic conversion
from AnsiString to Pointer...

-Flávio

On 5/12/06, Vinzent Hoefler <[hidden email]> wrote:

> Just found a bug of mine I was wondering about since about three days,
> and wanted to share the fun with you:
>
> -- 8< --
>
> // "How to raise the wrong exception" or
> // "Why automatic type conversion really sucks"
>
> {$MODE OBJFPC}
>
> program
>    Exception_Fun;
>
>
> uses
>    SysUtils;
>
>
> function Exception_Message : AnsiString;
> begin
>    exit ('Will never show up, of course.');
> end {Exception_Message};
>
> type
>    Not_Now = class (SysUtils.Exception);
>
> begin
>    try
>       raise Not_Now (Exception_Message);
>    except
>       on e : Not_Now do
>          WriteLn (StdErr, 'Caught it! Strange.');
>    end {try};
> end {Exception_Fun}.
>
> -- 8< --
>
> No error, no warning, no note, no hint: Of course, a class type is just
> a pointer, AnsiStrings can be pointers. Pointers can be converted to
> any other pointer type... *crash*
>
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Typecasting by accident

Matt Emson
> Weird, I wouldn't expect OBJFPC mode to allow automatic conversion
> from AnsiString to Pointer...

Um...
>       raise Not_Now (Exception_Message);

It's a CAST dude! Exception_Message is being case as Not_Now. That should
work fairly well in most dialects.t

M


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Typecasting by accident

etrusco
On 5/14/06, Matt Emson <[hidden email]> wrote:
> > Weird, I wouldn't expect OBJFPC mode to allow automatic conversion
> > from AnsiString to Pointer...
>
> Um...
> >       raise Not_Now (Exception_Message);
>
> It's a CAST dude! Exception_Message is being case as Not_Now. That should
> work fairly well in most dialects.t
>

No. Typecasts, as any other aspect of a language, has to have rules.
AFAIR this cast in Delphi would require another cast from AnsiString
to Pointer. And if typed pointers is enabled would require another
cast from Pointer to TObject.
OBJFPC is usually regarded as more strict than DELPHI mode, so I
wouldn't expect this lax cast to be allowed.

-Flávio
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Typecasting by accident

Jonas Maebe-2

On 15 mei 2006, at 18:09, Flávio Etrusco wrote:

>> It's a CAST dude! Exception_Message is being case as Not_Now. That  
>> should
>> work fairly well in most dialects.t
>
> No. Typecasts, as any other aspect of a language, has to have rules.
> AFAIR this cast in Delphi would require another cast from AnsiString
> to Pointer.

It doesn't.

> And if typed pointers is enabled would require another
> cast from Pointer to TObject.

No. {$t+} only influences implicit pointer conversions.


Jonas

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Typecasting by accident

Matt Emson
In reply to this post by etrusco

> No. Typecasts, as any other aspect of a language, has to have rules.
> AFAIR this cast in Delphi would require another cast from AnsiString
> to Pointer. And if typed pointers is enabled would require another
> cast from Pointer to TObject.

Nope. The C style cast is not type safe. Using the "as" operator is.

var
  p: pointer;
  i: integer;
begin
  i := 10;
  p := TObject(i); //will work, but is invalid
  p := (i as TObject); //should fail (not tried) because i is not compatible
end;

M

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Typecasting by accident

etrusco
In reply to this post by Jonas Maebe-2
I stand corrected. I've checked Delphi5 today and none of my
expectations where correct :-(
Of course I think that AnsiString being a native type would require
that (one) typecast just like any other (native type).

Of course I also think that any object should be cast to a mininum
common ancestor before being cast to any other class, but maybe it's
just me ;-)

-Flávio


On 5/15/06, Jonas Maebe <[hidden email]> wrote:

>
> On 15 mei 2006, at 18:09, Flávio Etrusco wrote:
>
> >> It's a CAST dude! Exception_Message is being case as Not_Now. That
> >> should
> >> work fairly well in most dialects.t
> >
> > No. Typecasts, as any other aspect of a language, has to have rules.
> > AFAIR this cast in Delphi would require another cast from AnsiString
> > to Pointer.
>
> It doesn't.
>
> > And if typed pointers is enabled would require another
> > cast from Pointer to TObject.
>
> No. {$t+} only influences implicit pointer conversions.
>
>
> Jonas
>
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Typecasting by accident

etrusco
In reply to this post by Matt Emson
I stand corrected. I've just checked Delphi5 and indeed it allows a
direct typecast from ansistring to any object/class :-/
But Delphi also allows direct cast from enumeration value to pointer
(which FPC doesn't allow), so maybe this is another nice oportunity to
be stricter than Delphi ;-)

Cheers,
Flávio

On 5/15/06, Matt Emson <[hidden email]> wrote:

>
> > No. Typecasts, as any other aspect of a language, has to have rules.
> > AFAIR this cast in Delphi would require another cast from AnsiString
> > to Pointer. And if typed pointers is enabled would require another
> > cast from Pointer to TObject.
>
> Nope. The C style cast is not type safe. Using the "as" operator is.
>
> var
>   p: pointer;
>   i: integer;
> begin
>   i := 10;
>   p := TObject(i); //will work, but is invalid
>   p := (i as TObject); //should fail (not tried) because i is not compatible
> end;
>
> M
>
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal