RE: [sv-ec] Virtual function call from base class constructor

From: Daniel Mlynek <daniel.mlynek_at_.....>
Date: Thu Jun 26 2008 - 00:36:38 PDT
i've fill :  <http://www.eda-stds.org/svdb/view.php?id=2429> 0002429 mantis
on that
 
 
 
DANiel

  _____  

From: Arturo Salz [mailto:Arturo.Salz@synopsys.com] 
Sent: Wednesday, June 25, 2008 11:51 PM
To: Jonathan Bromley; Gordon Vreugdenhil
Cc: Chris Spear; Daniel Mlynek; sv-ec@eda.org
Subject: RE: [sv-ec] Virtual function call from base class constructor



Jonathan,

 

With regards to your first question, the LRM says:

 

When using the super within new, super.new shall be the first statement
executed in the constructor.

 

So your code snippet is legal: the ternary operation is not a statement; it
is an argument expression.

 

I agree that the definition of what is the "first statement" can be further
improved, particularly, when it applies to harmless and seemingly
well-behaved code, such as Gord's example of initializing variables local to
the constructor - though perhaps not via virtual method calls. As written
now, however, such statements preceding the call to super.new would violate
the current LRM.

 

One detail that seems to be eluding this discussion is that SystemVerilog's
object-oriented mechanism is largely based on Java, not on C++ or C#. In
fact, the rule requiring super.new to be the first statement is a direct
derivation of Java's rule.

 

Likewise, Java's virtual method handling differs from C++. In Java, calling
a virtual method invokes the derived class's version. Since, the derived
class may not have been initialized at the point of the call, calling
(virtual or non-final) methods in a constructor will usually trigger strange
behavior or null-pointer exceptions. One way to avoid these problems is to
only call private methods in constrictors. Books on Java are full of dire
warnings against calling derived methods in constructors. For example:
"Thinking in Java", makes this point:

 

Conceptually, the constructor's job is to bring the object into existence
(which is hardly an ordinary feat). Inside any 

constructor, the entire object might be only partially formed-you can know
only that the base-class objects have been 

initialized, but you cannot know which classes are inherited from you. A
dynamically bound method call, however, 

reaches "outward" into the inheritance hierarchy. It calls a method in a
derived class. If you do this inside a constructor, 

you call a method that might manipulate members that haven't been
initialized yet-a sure recipe for disaster."

 

It is unfortunate that the LRM doesn't explicitly specify the behavior of
virtual methods in constructors. And that omission has lead to the current
discussion. But rather than attempt to copy C++, I would suggest that we
consider SV's pedigree in favor of the simpler Java model.

 

Regardless of where one falls in this discussion, one thing that we can all
agree on is that calling virtual methods from within constructors is not a
good practice and should be discouraged. I would propose we add a note
stating that this should be avoided - we might go further and  state that
doing so may result in undefined behavior, which would simply acknowledge
the reality that implementations seem to have diverged. The more complex C++
mechanism attempts to protect users, and while it its behavior is more
compartmentalized, it doesn't completely eliminate the problem - the
dependencies between (uninitialized) variables and the virtual method's use
of such variables is still there. 

 

            Arturo

 

-----Original Message-----
From: owner-sv-ec@eda.org [mailto:owner-sv-ec@eda.org] On Behalf Of Jonathan
Bromley
Sent: Wednesday, June 25, 2008 11:05 AM
To: Gordon Vreugdenhil
Cc: Chris Spear; Daniel Mlynek; sv-ec@eda.org
Subject: RE: [sv-ec] Virtual function call from base class constructor

 

 

> "super.new" must be "first".  What constitutes "first"?

 

yes; for example, is this OK?  I can easily see why it might

not be, but I can also see why I might wish to do it:

 

  class C; function new(int N); ...

  class D extends C;

    function new(int N);

      super.new( N>0 ? N : 0 );

      ...

 

 

> >   c = D::new();

> > Is there any fundamental problem with this that I've missed?

> 

> I don't have too much concern over this.

 

But I had not thought about Dave Rich's point:

> [DR] Except that the "this" handle is not available

> in static methods, and needs to be available in a constructor.

 

Thanks

-- 

Jonathan Bromley, Consultant

 

DOULOS - Developing Design Know-how

VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

 

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK

Tel: +44 (0)1425 471223                   Email: jonathan.bromley@doulos.com

Fax: +44 (0)1425 471573                           Web: http://www.doulos.com

 

This message may contain personal views which 

are not the views of Doulos Ltd., unless specifically stated.

 

-- 

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 Jun 26 00:38:31 2008

This archive was generated by hypermail 2.1.8 : Thu Jun 26 2008 - 00:39:18 PDT