There was some discussion of this issue on the reflector in the thread starting with post: http://www.eda.org/sv-ec/hm/6221.html I think there is consensus on that the intent is that initializers run "earlier" than constructors so that constructors can override initializers. It is not clear that there is consensus about what that means in non-trivial cases. In particular, there are visible artifacts of base/derived initializer sequencing that are important to determine. Example 1: class base; int x = 1; function new(); x = 2; endfunction endclass class derived extends base; int y = x; endclass Example 2: class base; int x = 1; function new(int y); x = y; endfunction endclass class derived extends base; int y = x; function new; super.new(y); endfunction endclass The question of whether initializers are interleaved with construction directly impacts the result of the above examples. For initialization with literals, most of the difference is immaterial. For initialization with base property references, the completeness of the base class initialization is important. In ISO C++ this is avoided by disallowing in-class initialization of non-static members. In Java, the ordering is: initialize everything to default in deepest base class to derived class order run initializers run constructor body Java does NOT allow base constructor arguments to refer to members of the derived class in order to avoid the question raised in example 2. If initializers do not refer to members in base classes or call virtual methods then there is no issue. There are at least the following choices that we could make: 1) do nothing; the behavior is undefined 2) explicitly state that the behavior is implementation dependent 3) disallow initializers that refer to inherited members or virtual methods 4) follow the Java ordering as outlined above 5) follow the ordering that Arturo suggested: run initializers for all properties call superclass constructor call constructor In considering (4) and (5), I definitely prefer the Java model since there is better "locality" of knowledge. A derived class "knows" whether it has a potential initialization dependency on the base -- it does not (should not) know whether the base class initializers via initializers or constructors. If the derived class has a dependency on the base members, that dependency should be described without local member initialization dependencies but that determination can be done locally. So philosophically, I consider example 1 and 2 to be quite different. In example 1, the derived class is depending on an inherited property. In example 2, the derived class is explicitly creating a cycle between an inherited property and a derived property. As with Java, I would like to argue that base class initialization should be opaque and complete before derived class initialization occurs. I would have no objection to following Java's rule on constructors along with the initialization sequencing (i.e. disallowing local member references in the super.new call). I would object to the ordering in (5) since that reduces the "opaque" nature of base class initialization which I believe is an important characteristic for robust OO designs. 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 Fri Apr 24 10:05:38 2009
This archive was generated by hypermail 2.1.8 : Fri Apr 24 2009 - 10:05:49 PDT