Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2006-05

Typecasting by accident

9 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Vinzent Hoefler

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*

memsom
to Vinzent Hoefler
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

Flávio Etrusco
to Vinzent Hoefler: Just found a bug of mine I was wondering about since about three days, and wanted to…

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

-Flávio

Vinzent Hoefler wrote 45 lines
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 - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Matt Emson
to Flávio Etrusco
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

Flávio Etrusco
to Matt Emson
Matt Emson wrote 9 lines
> 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

Jonas Maebe
to Flávio Etrusco
Flávio Etrusco wrote 7 lines
> 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

Matt Emson
to Flávio Etrusco: No. Typecasts, as any other aspect of a language, has to have rules. AFAIR this cast in…
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

Flávio Etrusco
to Jonas Maebe: It doesn't. No. {$t+} only influences implicit pointer conversions. Jonas

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

Jonas Maebe wrote 21 lines
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
Flávio Etrusco
to Matt Emson: Nope. The C style cast is not type safe. Using the "as" operator is. var p: pointer; i:…

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

Matt Emson wrote 23 lines
> 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 - http://lists.freepascal.org/mailman/listinfo/fpc-pascal