RE: [sv-ec] sub-class constructor

From: Alsop, Thomas R <thomas.r.alsop_at_.....>
Date: Thu Feb 12 2009 - 08:56:12 PST
Hi Gord,

I didn't quite understand the two examples you gave below. Are you basically saying the C++ infers arguments passed in super.new() child calls and that SV is not clear on this?

I can appreciate the Doulos documentation given the shortcomings in the SV LRM.  Wasn't sure if this was given as SV gospel or methodology.  Seems like it should be a methodology statement.  I believe the VMM has this as a 'Rule' or 'Guideline', i.e. always call super.new(), with arguments if needed, when child constructors are defined.  

The virtual aspect comes into play depending on the usage model, right?  If you want your base classes constructors to be 'overriden' (i.e. polymorphism) but still include the super.new() functionality, then your child new() definition would call super.new().  If you want to completely change what all the extended classes do up to the base, then the child new() definition would not call super.new(), right?

In the case of non-virtual child new() calls, again, calling super.new() really depends on whether the end user want to completely override the super.new() or not.  Although it doesn't sound like good practice, this may be something they want or need in the extended class.  

Seems to me that we shouldn't define the SV LRM to implicitly call super.new() in child extensions, rather we should state that this will not be the case and let the methodologies that are out there recommend this practice.

Thanks, -Tom

-----Original Message-----
From: owner-sv-ec@server.eda.org [mailto:owner-sv-ec@server.eda.org] On Behalf Of Gordon Vreugdenhil
Sent: Thursday, February 12, 2009 8:18 AM
To: jonathan.bromley@doulos.com
Cc: Bresticker, Shalom; sv-ec@server.eda.org; Feldman, Yulik
Subject: Re: [sv-ec] sub-class constructor



jonathan.bromley@doulos.com wrote:
> Shalom,
> 
[...]

> For my part, I'll take an action to get that cleaned-up in
> our GRG.  However, the SV LRM could perhaps be a little
> more helpful than it is in clarifying this behaviour. There
> are some corner cases that don't seem to me to be too 
> clear.  In particular, any attempt to compute the arguments
> to super.new() will seriously muddy the waters:
> 
>   class C;
>     function new(int x);
>     ...
>   endclass : C
>  
>   class D extends C;
>     function new(bit b);
>       if (b)
>         super.new(-1);
>       else
>         super.new(1);
>    ...
> 
> Is that legal?  

No, it isn't.

> If not, could it be made legal thus?
> 
>    function D::new(bit b);
>      super.new(b? -1: 1);

Yes.

> Would it be legal to call a function to compute
> the arguments? (Evidently, not a *member* function.)

Argument evaluation is an expression evaluation; any such
evaluation is fine.  Member functions are not in fact
disallowed by the LRM although the semantics of such
calls are ill-defined.  For example, C++ is very clear
that the effective vtbl (set of virtual method bindings)
follows the "current" type of the base class constructor
during construction.  SV is not at all clear on this and
users would be well advised to not rely on the semantics
of such calls.

Example:

module top;
    class C;
       virtual function int f();
          return 1;
       endfunction
       int x = f();            // ill-defined in SV
    endclass
    class D extends C;
       function int f();
          return 2;
       endfunction
       int y = f();            // ill-defined in SV
    endclass

    D d = new;
    initial $display(d.x,,d.y);
endmodule


C++ equivalent:

#include <iostream>
class foo {
   public:
     virtual int f() { return 1; }
     int x;
     foo() { x = f(); }   // C++ compliant call to foo::f even
                          // during derived object construction
};

class bar : public foo {
   public:
     virtual int f() { return 2; }
     int y;
     bar() { y = f(); }   // C++ compliant call to bar::f
};


main()
{
    bar *b = new bar;
    std::cout << b->x << "   " << b->y << std::endl;
}



> In all such cases, super.new() is not the first
> executable code in D::new() even if it is
> lexically the first code to appear.

That is true and one could spoof all sorts of bad behavior
by creating a dummy property and using a function call
to evaluate.  Suggestion -- don't do that; it will likely
hurt.

Other than for rather simple, definitely "local" value
construction, I would be careful about making assumptions
about ordering and if you want to be very careful, do
the initialization explicitly in the constructor chain,
rather than using initializers.  Finally, as indicated
above, I would not rely on any virtual method calls in SV
constructors at this point since the semantics are not
explicitly defined.

Gord.
-- 
--------------------------------------------------------------------
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.
Received on Thu Feb 12 08:57:27 2009

This archive was generated by hypermail 2.1.8 : Thu Feb 12 2009 - 08:58:06 PST