Hello Folks!
Prof Abimbola Olowofoyeku wrote:
object is class
returns True if object is an instance of the class denoted by class or one of its descendants, and False otherwise.
That's exactly what I need. According to Frank, there's already a plan to put it into GPC, so I'll wait and see...
Alternatively, I could need a mechanism to absorb the runtime error fired by "as" before it interrupts the program.
In Delphi, from what the help file says, the program should not compile if the typecasting is wrong. GPC could do the same.
??? How should the compiler know? I mean, the object type of a pointer at runtime is a matter of runtime.
Yours
Markus
On 19 Mar 01, at 19:36, Markus Gerwinski wrote:
[...]
In Delphi, from what the help file says, the program should not compile if the typecasting is wrong. GPC could do the same.
??? How should the compiler know? I mean, the object type of a pointer at runtime is a matter of runtime.
The compiler should know what an object type is and whether an object that purports to point to it is a pointer to the right type.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) Author of: Chief's Installer Pro for Win32 http://www.bigfoot.com/~African_Chief/chief32.htm Email: African_Chief@bigfoot.com
Markus Gerwinski wrote:
Alternatively, I could need a mechanism to absorb the runtime error fired by "as" before it interrupts the program.
In Delphi, from what the help file says, the program should not compile if the typecasting is wrong. GPC could do the same.
??? How should the compiler know? I mean, the object type of a pointer at runtime is a matter of runtime.
I think what's meant is if the types involved are not ancestors of each other, i.e. in `foo [ia]s bar' if foo is of declared type ^baz, and neither bar is derived from baz or vice versa, then the compiler can know that the check is wrong.
There's another trivial case when bar is an ancestor of baz. In this case, the check is always true. I don't know what Delphi does in this case, but I think GPC should at least give a warning, like it does when comparing an unsigned value >= 0.
The interesting case, of course, is when baz is an ancestor of bar, and this requires a runtime check.
Frank
On 20 Mar 2001, at 0:51, Frank Heckenbach wrote:
[...]
??? How should the compiler know? I mean, the object type of a pointer at runtime is a matter of runtime.
I think what's meant is if the types involved are not ancestors of each other, i.e. in `foo [ia]s bar' if foo is of declared type ^baz, and neither bar is derived from baz or vice versa, then the compiler can know that the check is wrong.
There's another trivial case when bar is an ancestor of baz. In this case, the check is always true. I don't know what Delphi does in this case, but I think GPC should at least give a warning, like it does when comparing an unsigned value >= 0.
The interesting case, of course, is when baz is an ancestor of bar, and this requires a runtime check.
This little program shows how Delphi would handle it;
uses classes;
type f1 = class (TStringList) Procedure foo; virtual; end; type f2 = class (f1) Procedure bar; virtual; end;
procedure f1.foo; begin end; procedure f2.bar; begin end;
var h1 : f1; h2 : f2; begin h1 := f1.create; h2 := f2.create;
{--- these all return TRUE ---} Writeln (h1 is f1); Writeln (h2 is f2); Writeln (h2 is f1); Writeln (h1 is TStringList); Writeln (h2 is TStrings); Writeln (h2 is TObject); Writeln (h1 is TStrings); Writeln (h1 is TObject);
{--- this returns FALSE ---} Writeln (h1 is f2);
{--- these three each cause a compile-time error ---} Writeln (h2 is TCollection); Writeln (h2 is TList); Writeln (h2 is TComponent);
{----} h1.free; h2.free; end.
Best regards, The Chief --------- Prof. Abimbola Olowofoyeku (The African Chief) Author of Chief's Installer Pro v5.25 for Win32 Email: African_Chief@bigfoot.com http://www.bigfoot.com/~african_chief/
Prof. A Olowofoyeku (The African Chief) wrote:
On 20 Mar 2001, at 0:51, Frank Heckenbach wrote:
[...]
??? How should the compiler know? I mean, the object type of a pointer at runtime is a matter of runtime.
I think what's meant is if the types involved are not ancestors of each other, i.e. in `foo [ia]s bar' if foo is of declared type ^baz, and neither bar is derived from baz or vice versa, then the compiler can know that the check is wrong.
There's another trivial case when bar is an ancestor of baz. In this case, the check is always true. I don't know what Delphi does in this case, but I think GPC should at least give a warning, like it does when comparing an unsigned value >= 0.
The interesting case, of course, is when baz is an ancestor of bar, and this requires a runtime check.
This little program shows how Delphi would handle it;
uses classes;
type f1 = class (TStringList) Procedure foo; virtual; end; type f2 = class (f1) Procedure bar; virtual; end;
procedure f1.foo; begin end; procedure f2.bar; begin end;
var h1 : f1; h2 : f2; begin h1 := f1.create; h2 := f2.create;
{--- these all return TRUE ---}
And should all give a warning (in GPC) because it's clear at compile time that they're true, and therefore the checks are either superfluous or not what the programmer means...
Writeln (h1 is f1); Writeln (h2 is f2); Writeln (h2 is f1); Writeln (h1 is TStringList); Writeln (h2 is TStrings); Writeln (h2 is TObject); Writeln (h1 is TStrings); Writeln (h1 is TObject);
{--- this returns FALSE ---} Writeln (h1 is f2);
That's the interesting case because h1 could (at runtime) be an f2.
{--- these three each cause a compile-time error ---}
Makes sense.
Writeln (h2 is TCollection); Writeln (h2 is TList); Writeln (h2 is TComponent);
{----} h1.free; h2.free; end.
Frank
On 20 Mar 2001, at 16:23, Frank Heckenbach wrote:
[...]
The interesting case, of course, is when baz is an ancestor of bar, and this requires a runtime check.
This little program shows how Delphi would handle it;
uses classes;
type f1 = class (TStringList) Procedure foo; virtual; end; type f2 = class (f1) Procedure bar; virtual; end;
procedure f1.foo; begin end; procedure f2.bar; begin end;
var h1 : f1; h2 : f2; begin h1 := f1.create; h2 := f2.create;
{--- these all return TRUE ---}
And should all give a warning (in GPC) because it's clear at compile time that they're true, and therefore the checks are either superfluous or not what the programmer means...
The example is just a trivial one. In Delphi, event handlers normally take a "Sender : TObject" parameter which normally points to the control that generated the event. Inside the event handler (method) you may need to know the exact type of the "Sender". It is in such cases that the "if Sender is TEdit" scenario will be necessary (almost everything is a descendant of TObject and TObject itself doesn't do very much).
{--- this returns FALSE ---} Writeln (h1 is f2);
That's the interesting case because h1 could (at runtime) be an f2.
If you "Constructed" it earlier with "h1 := f2.create;" instead of "h1 := f1.create;" then "h1 is f2" will also be TRUE. Also, if somewhere down the line you do "h1 := h2;" then "h1 is f2" will also be TRUE (but you will get an exception when you come to free h1 unless you have overridden the destructor to cater for situations where "h1 is f2".
Interestingly, the compiler does not accept the assignment: "h2 := h1;"
Best regards, The Chief --------- Prof. Abimbola Olowofoyeku (The African Chief) Author of Chief's Installer Pro v5.25 for Win32 Email: African_Chief@bigfoot.com http://www.bigfoot.com/~african_chief/
Prof. A Olowofoyeku (The African Chief) wrote:
{--- this returns FALSE ---} Writeln (h1 is f2);
That's the interesting case because h1 could (at runtime) be an f2.
If you "Constructed" it earlier with "h1 := f2.create;" instead of "h1 := f1.create;" then "h1 is f2" will also be TRUE. Also, if somewhere down the line you do "h1 := h2;" then "h1 is f2" will also be TRUE
Yes, that's what I mean.
(but you will get an exception when you come to free h1 unless you have overridden the destructor to cater for situations where "h1 is f2".
Doesn't Delphi support virtual destructors? Even BP does...
Interestingly, the compiler does not accept the assignment: "h2 := h1;"
No, and it shouldn't because the types don't match. `h2 := h1 as f2' should work (with the check and possibly an error).
Frank
On 20 Mar 01, at 17:52, Frank Heckenbach wrote:
That's the interesting case because h1 could (at runtime) be an f2.
If you "Constructed" it earlier with "h1 := f2.create;" instead of "h1 := f1.create;" then "h1 is f2" will also be TRUE. Also, if somewhere down the line you do "h1 := h2;" then "h1 is f2" will also be TRUE
Yes, that's what I mean.
(but you will get an exception when you come to free h1 unless you have overridden the destructor to cater for situations where "h1 is f2".
Doesn't Delphi support virtual destructors? Even BP does...
Yes, it does - but I am not sure which destructor you would be calling after such an assignment. Remember that instances of classes are pointers to the objects - so in the assignment, what you are moving around are pointers, and there may be gotchas there.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) Author of: Chief's Installer Pro for Win32 http://www.bigfoot.com/~African_Chief/chief32.htm Email: African_Chief@bigfoot.com