On 4 Jun 2003 at 0:41, Frank Heckenbach wrote:
I recently came about the issue of overriding non-virtual methods by virtual ones. GPC currently allows this, but it may be slightly confusing. BP allows it as well, so we shouldn't forbid it. But should we warn? (Always or unless `--borland-pascal' was given?)
A warning except under '--borland-pascal' is fine.
OK (chief52*.pas). (Also no warning under `--delphi', or should it?)
I think there should also be no warning under '--delphi'.
Another thing - an object with virtual methods but no constructor causes confusion under BP - e.g.,
type a = object procedure p; end;
b = object (a) procedure p; virtual; end;
procedure a.p; begin writeln ('a'); end;
procedure b.p; begin writeln ('b'); end;
var foo : a; bar : b;
begin foo.p; bar.p; end.
If this example is compiled with BP then, only 'a' gets printed (BP gives no warning, but silently compiles what it considers to be a faulty program).
Compiled with FPC, you get these warnings: a.pas(6,7) Warning: Virtual methods are used without a constructor in "b" a.pas(30,2) Warning: Variable "bar" does not seem to be initialized
When you run the program, 'a' gets printed, and then a GPF.
Compiled with Delphi, you get no warning, and both 'a' and 'b' get printed. Ditto with GPC, even with '--borland-pascal'.
Add a constructor and a constructor call before the call to 'b.p' and everything is alright under BP and FPC.
So, GPC's current treatment of objects with virtual methods but no constructor seems (at least with the trivial examples) to be consistent with Delphi, but not with BP when using '--borland-pascal'.
For GPC, your observed behaviour is expected. With what I know about BP, it isn't -- and in fact, when I tested it with BP, it gave a runtime error 210 (range checking or invalid object reference), and with `{$R-}', it hung. I don't know so much about Delphi and FPC, so I can't tell whether it's the expected behaviour there. Maybe it isn't guaranteed to work in Delphi and just happened to in your test (just like your BP test happened to not crash). Do you find anything in the documentation?
This is all I can find:
"A constructor is a special method that initializes an object containing virtual methods.
Syntax constructor Method (<parameter list>);
Remarks A constructor must be declared with the reserved word constructor.
The constructor initializes an object by setting the link between the object and the virtual method table with addresses of the code for its virtual methods.
A constructor can also be used to initialize the object data fields."
So, I guess that the first statement means that a constructor is expected when there are virtual methods. The penultimate statement also seems to indicate that a constructor is treated as something special by the BP compiler (and therefore probably involves some special processing), whereas I don't believe that this is necessarily the case under GPC. How/where does GPC achieve it's "setting the link between the object and the virtual method table with addresses of the code for its virtual methods"?
PS: I know that, under BP and Delphi, a call to the constructor automatically zeroes out all the object's fields as appropriate (e.g., pointers are set to Nil, numbers are set to zero, and strings are set to empty). I am not sure that this is a behaviour that GPC should imitate - but the fact that GPC does not do this automatically is currently one of the "gotchas" awaiting those coming to GPC from BP and Delphi.
In all my Pascal code, I found just one place (and some GPC test programs) where objects have virtual methods and no constructor. These can be fixed easily.
So I think a warning cannot hurt, and unless someone protests, I'll add it (not for abstract object types, of course). (chief51*.pas)
I agree that a warning cannot hurt.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/