RE: [sv-ec] member initialization at declaration vs. constructor - order issue

From: Daniel Mlynek <daniel.mlynek_at_.....>
Date: Mon Sep 01 2008 - 02:37:18 PDT
Steven Sharp with order of execution prposd by yoou will wirk differently -
his argument was that base class need to be fully initiliazed before
creating child class - so default initialization of child class prpoerties
need to be done after return from super.new.


	class C;
                int i;
                function new(input int v);
                        i = v;
                        $display("C %d", i);
                        $display("C %d", v);
                endfunction
        endclass
 
        class CC extends C;
                int j=i;
                function new;
                        super.new(123);
                        $display("CC %d",i);
                        $display("CC %d",j);
                endfunction
        endclass
 
DANiel
-----Original Message-----
From: owner-sv-ec@server.eda.org [mailto:owner-sv-ec@server.eda.org] On
Behalf Of Arturo Salz
Sent: 29 sierpnia 2008 20:29
To: Gordon Vreugdenhil; Rich, Dave
Cc: Daniel Mlynek; Steven Sharp; sv-ec@server.eda-stds.org
Subject: RE: [sv-ec] member initialization at declaration vs. constructor -
order issue

I agree that we don't have a consensus yet on some of this. But I'd like to
answer Daniel's original question regarding the intent of property
declaration initializers and their relationship with constructor functions.
The intent was as Steven wrote, with one slight difference:

A call to a class constructor should do the following, in this order:

1. Allocate memory for the object (the entire object) 2. Initialize each
member (of the entire object) to the default value specified in its
declaration, if any, else to the default initialization value.
3. Call the class constructor
3.a If the class is not a base class then the first thing the constructor
executes is the base class constructor (lets put aside the ambiguity related
to "first") - and so on recursively until reaching the base class.
4. Execute the body of the constructor.

This is the intent for allowing constructor methods to override the property
declaration initializers.

Note that step 3.a above could also be implemented by initializing each
member to its default initialization value first and then initializing
members with the value specified as a default initialization.

To explain this, consider the following example:

class B;
  int a = 5;

  function new( int x );
    a = x;
  endfunction
endclass

class C extends B;
  int i = 123;
  int j;

  function new();
    super.new( j );
    j = i;
  endfunction
endclass

C q = new;

Right before B::new begins execution, the class properties should be:
 a = 5
 i = 123
 j = 0
After execution of B::new, the values are:
 a = 0
 i = 123
 j = 0
Once execution of C::new, the values are:
 a = 0
 i = 123
 j = 123

I hope this helps.

I agree with Steven's remark that it makes sense to initialize properties in
the order they were declared - and base class to derived class. But the LRM
does not state this explicitly.

	Arturo

-----Original Message-----
From: owner-sv-ec@eda.org [mailto:owner-sv-ec@eda.org] On Behalf Of Gordon
Vreugdenhil
Sent: Friday, August 29, 2008 8:58 AM
To: Rich, Dave
Cc: Daniel Mlynek; Steven Sharp; sv-ec@eda-stds.org
Subject: Re: [sv-ec] member initialization at declaration vs. constructor -
order issue


Some of this also relates to the role of "this" in terms of what
initializers can access and about exactly what the restriction that
"super.new() must be the first statement" means in the presence of function
calls in initializers.  I don't think we have consensus on all of that yet,
particularly when virtual method calls might be in play.

Gord.


Rich, Dave wrote:
> I agree with what Steven (and now Françoise) said about "this" being 
> undefined in a constructor before the return from super.new(). So the 
> reference to i would be an error. I wish the LRM would make it an 
> explicit compiler error to reference a non-static member before 
> super.new()
> 
> Dave
> 
> 
>> -----Original Message-----
>> From: owner-sv-ec@server.eda.org [mailto:owner-sv-ec@server.eda.org] 
>> On Behalf Of Daniel Mlynek
>> Sent: Friday, August 29, 2008 3:24 AM
>> To: 'Steven Sharp'
>> Cc: sv-ec@server.eda-stds.org
>> Subject: RE: [sv-ec] member initialization at declaration vs. 
>> constructor
>> - order issue
>>
>> Similar problem :
>> class C;
>>     int i=123;
>>     function new();
>>         int j=i;  //this initialization is performed before I 
>> initialization at declaration?
>>         //super.new(j);//implicit or explicit What would be the value 
>> if j according to yours understanding? 0 or 123?
>>
>>
>> -----Original Message-----
>> From: owner-sv-ec@server.eda.org [mailto:owner-sv-ec@server.eda.org] 
>> On Behalf Of Steven Sharp
>> Sent: 29 sepia 2008 00:15
>> To: sv-ec@server.eda-stds.org; daniel.mlynek@aldec.com
>> Subject: Re: [sv-ec] member initialization at declaration vs. 
>> constructor
>> -
>> order issue
>>
>>
>>> From: "Daniel Mlynek" <daniel.mlynek@aldec.com> I've hit  another 
>>> problem connected with order of execution of declaration 
>>> initialization vs.. constructor (imho allowing declaration 
>>> initialization for class members was good idea at all) LRM doesn't 
>>> define how it should be done. My guess is that:
>>> 1st initialization from declaration should be done in order from 
>>> base class to child class 2nd constructor chain should be executed - 
>>> as described in LRM from base to child
>> The problem with this ordering is that an initializer on a 
>> declaration in the child class could reference a property in the base 
>> class that is initialized by the base class constructor.  The child 
>> class should not be dependent on how the construction of the base 
>> class was done.  Therefore the base class should be completely 
>> initialized before the initialization of the child class is started.
>>
>>
>>> But for classes inheriting some other class LRM says:
>>> "Every class has a default (built-in) new method. The default 
>>> constructor first calls its base class constructor (super.new() as 
>>> described in 8.14) and then proceeds to initialize each member of 
>>> the current object to its default (or uninitialized value)."
>>> Most interesting is "proceeds to initialize each member of the 
>>> current object to its default (or uninitialized value)." I thought 
>>> that uninitialized value is same as default, anyway why constructor 
>>> need to do some initialization if the value should be default (which 
>>> means that value is hold in variable if no initialization or assignment
was done  ).
>>> But one can understand this sentence differently - default value is 
>>> a value from initialization at declaration - because it has to be 
>>> assigned
>> I believe this is how you must interpret the sentence, though I agree 
>> it is not entirely clear.
>>
>> The order should be
>>
>> 1. Call the base class constructor.
>> 2. Initialize each member to the default value specified in its 
>> declaration,
>>    if any, else to the default initialization value.
>> 3. Execute the body of the constructor.
>>
>> Though the LRM does not say so, it would also make sense to 
>> initialize the properties in the order they were declared, since the 
>> initializer of a property might refer to a property declared earlier.
>>
>> This leaves only one small hole where you could refer to the value of 
>> a property before it is initialized.  That is the one you use in your
>> example: the actual arguments to the super.new() call, if you specify 
>> it explicitly.  In your example, you refer to a property of the local 
>> class, which is not initialized until after the super.new() call.  
>> You could also refer to a property of the base class, which might be 
>> initialized by the
>> super.new() call itself.  I think we just have to regard that as bad
code.
>>
>> To make that code illegal, you would have to specify special scoping 
>> rules to the actual arguments of the super.new() call.  You would 
>> have to regard the scope the same way as if you were inside a static
method of the class:
>> you have access to the locals of the new() method and to static 
>> properties, but not to nonstatic properties.  Another way to do it 
>> would be to treat the value of 'this' as if it were null until after 
>> the super.new() call returned.
>>
>>> I totally don't understand what was the goal of adding this sentence 
>>> to
>> LRM.
>>
>> I suspect it was intended to answer your question about the order.  
>> You just have to interpret "default" in that sentence as meaning the 
>> value on the declaration.  That would explain why the sentence treats 
>> it as something different from the uninitialized value.
>>
>>
>>> What should be the results in your opinion?
>> 123 undefined 123 123
>>
>> Making sure that the base class is initialized before the derived 
>> class is more important than someone trying to pass an uninitialized 
>> property as an argument to the base constructor.  Even with your 
>> suggested ordering, I could still reference an uninitialized value in the
base class anyway.
>>
>> With your suggested ordering, there would be a problem with
>>
>>         class C;
>>                 int i;
>>                 function new(input int v);
>>                         i = v;
>>                         $display("C %d", i);
>>                         $display("C %d", v);
>>                 endfunction
>>         endclass
>>
>>         class CC extends C;
>>                 int j=i;
>>                 function new;
>>                         super.new(123);
>>                         $display("CC %d",i);
>>                         $display("CC %d",j);
>>                 endfunction
>>         endclass
>>
>> With your suggested ordering, the result of this would be
>>
>>   123 123 123 undefined
>>
>> With my suggested ordering, the result of this would be
>>
>>   123 123 123 123
>>
>>> Is the LRM description clear in this matter in your opinion?
>> It could use some improvement.
>>
>>
>>> Do you finding class member initialization at declaration useful 
>>> feature - or are you regretting that someone have vote it in into 
>>> the
>> standard ?
>>
>> It would certainly be simpler to have left it out and require users 
>> to insert assignments into the constructor instead (after any 
>> super.new() call).  But as long as it is understood to be equivalent 
>> to that, it does not cause any real problems.
>>
>>
>> Steven Sharp
>> sharp@cadence.com
>>
>>
>> --
>> This message has been scanned for viruses and dangerous content by 
>> MailScanner, and is believed to be clean.
>>
>>
>> --
>> This message has been scanned for viruses and dangerous content by 
>> MailScanner, and is believed to be clean.
> 
> 

--
--------------------------------------------------------------------
Gordon Vreugdenhil                                503-685-0808
Model Technology (Mentor Graphics)                gordonv@model.com


-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.


-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.



-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Mon Sep 1 02:46:39 2008

This archive was generated by hypermail 2.1.8 : Mon Sep 01 2008 - 02:47:24 PDT