Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Constructor Inheritance Behaviour Difference Between XE2 and Berlin


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 6 - Last Post: Dec 22, 2016 8:39 AM Last Post By: Rudy Velthuis (...
Sam Eaton

Posts: 1
Registered: 1/2/17
Constructor Inheritance Behaviour Difference Between XE2 and Berlin  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 2, 2016 5:30 AM
I have recently been involved in upgrading a project from XE2 to Berlin. Upon investigating one particular crash it seems that there's a difference with the way the keyword inherited works between the two versions. I have made a very simple console project to demonstrate this:

program Project1;
 
{$APPTYPE CONSOLE}
 
{$R *.res}
 
uses
  System.SysUtils,
  Generics.Collections;
 
type
  TTest = class(TList<string>)
  public
    constructor SomeCreate;
  end;
 
  constructor TTest.SomeCreate;
  begin
    inherited;
    Add('Some String');
  end;
 
var
  test : TTest;
begin
  try
    test := TTest.SomeCreate;
    Writeln(test[0]);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.


Run the code in XE2 and note that it works and then run it in Berlin and note the crash when Add is called. It seems as though the inherited TList is not being constructed in the same way. Is this change intentional?

Edited by: Sam Eaton on Dec 2, 2016 5:31 AM

Edited by: Sam Eaton on Dec 2, 2016 5:45 AM
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: Constructor Inheritance Behaviour Difference Between XE2 and Berlin [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 3, 2016 8:27 AM   in response to: Sam Eaton in response to: Sam Eaton
Am 02.12.2016 um 14:45 schrieb Sam Eaton:
I have recently been involved in upgrading a project from XE2 to Berlin. Upon investigating one particular crash
it seems that there's a difference with the way the keyword inherited
works between the two versions. I have
made a very simple console project to demonstrate this:

Hello,

your question is better asked in the embarcadero.public.delphi.rtl group.

This here is about issues with the bugtracking system and usually not
with specific bugs as such afaik.

Greetings

Markus
Lajos Juhasz

Posts: 801
Registered: 3/14/14
Re: Constructor Inheritance Behaviour Difference Between XE2 and Berlin [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 3, 2016 10:15 AM   in response to: Sam Eaton in response to: Sam Eaton
Sam Eaton wrote:

I have recently been involved in upgrading a project from XE2 to
Berlin. Upon investigating one particular crash it seems that there's
a difference with the way the keyword inherited works between the two
versions. I have made a very simple console project to demonstrate
this:

program Project1;
 
{$APPTYPE CONSOLE}
 
{$R *.res}
 
uses
  System.SysUtils,
  Generics.Collections;
 
type
  TTest = class(TList<string>)
  public
    constructor SomeCreate;
  end;
 
  constructor TTest.SomeCreate;
  begin
    inherited;
    Add('Some String');
  end;
 
var
  test : TTest;
begin
  try
    test := TTest.SomeCreate;
    Writeln(test[0]);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.


Run the code in XE2 and note that it works and then run it in Berlin
and note the crash when Add is called. It seems as though the
inherited TList is not being constructed in the same way. Is this
change intentional?

I was able to reproduce this problem and also to find a workaround. For
some reason the inherited in the constructor wasn't calling the
constructor. My fix was to explicitly call the Create constructor for
the generic class:

  constructor TTest.SomeCreate;
  begin
    inherited Create;
    Add('Some String');
  end;


This has fixed the issue, but IMHO it's a bug.
Alex Belo

Posts: 626
Registered: 10/8/06
Re: Constructor Inheritance Behaviour Difference Between XE2 and Berlin [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 3, 2016 7:58 PM   in response to: Lajos Juhasz in response to: Lajos Juhasz
Lajos Juhasz wrote:

I was able to reproduce this problem and also to find a workaround.
For some reason the inherited in the constructor wasn't calling the
constructor. My fix was to explicitly call the Create constructor for
the generic class:

  constructor TTest.SomeCreate;
  begin
    inherited Create;
    Add('Some String');
  end;


This has fixed the issue, but IMHO it's a bug.

Hmm... If behaviour is different we can treat this as bug.

But from other hand now by default compiler is searching for inherited
constructor with the same name and can not find it; it looks more
logical decision. Really, if base class has 2 constructors what
constructor should be called by default "inherited;" operator?..

Perhaps compiler should emit a warning in such case.

--
Alex
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Constructor Inheritance Behaviour Difference Between XE2 and Berlin [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 22, 2016 8:15 AM   in response to: Alex Belo in response to: Alex Belo
Alex Belo wrote:

This has fixed the issue, but IMHO it's a bug.

Hmm... If behaviour is different we can treat this as bug.

No. The previous way it worked was a bug that seems to have been
corrected.

--
Rudy Velthuis http://www.rvelthuis.de

"Money is better than poverty, if only for financial reasons."
-- Woody Allen, From 'Without Feathers' 1976.
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Constructor Inheritance Behaviour Difference Between XE2 and Berlin [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 22, 2016 8:39 AM   in response to: Alex Belo in response to: Alex Belo
Alex Belo wrote:

Perhaps compiler should emit a warning in such case.

Since it is valid to call inherited even if there is no ancestor
method/constructor of the same name, it should at most be a hint and it
should be possible to turn it off. IMO.

--
Rudy Velthuis http://www.rvelthuis.de

"Why is propaganda so much more successful when it stirs up
hatred than when it tries to stir up friendly feeling?"
-- Bertrand Russell
Rudy Velthuis (...


Posts: 7,731
Registered: 9/22/99
Re: Constructor Inheritance Behaviour Difference Between XE2 and Berlin [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 22, 2016 8:14 AM   in response to: Lajos Juhasz in response to: Lajos Juhasz
Lajos Juhasz wrote:

I was able to reproduce this problem and also to find a workaround.
For some reason the inherited in the constructor wasn't calling the
constructor. My fix was to explicitly call the Create constructor for
the generic class:

  constructor TTest.SomeCreate;
  begin
    inherited Create;
    Add('Some String');
  end;


This has fixed the issue, but IMHO it's a bug.

If called inside SomeCreate, inherited should try to call the same
constructor with the **same** **signature** (name and parameters).
There is no parameterless constructor SomeCreate in TList<T>, so
nothing gets called.

It is not a bug, it is a wrong expectation.

I do agree that this could at least be a hint from the compiler: "there
is no inherited method to call" or some such. But since using inherited
even if there is no ancestor method to call, is valid code, it should
be possible to turn it off.

--
Rudy Velthuis http://www.rvelthuis.de

"Basically, I no longer work for anything but the sensation I
have while working."
-- Albert Giacometti (sculptor)

Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02