Re: [sv-ec] sub-class constructor

From: Gordon Vreugdenhil <gordonv_at_.....>
Date: Thu Feb 12 2009 - 08:18:24 PST
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.
Received on Thu Feb 12 08:19:24 2009

This archive was generated by hypermail 2.1.8 : Thu Feb 12 2009 - 08:20:04 PST