www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - BUG: Constructor chaining and const member intialization

reply Garett Bass <garettbass studiotekne.com> writes:
The code sample below highlights three related issues with constructor chaining
under the current DMD version:

1. BUG: chaining constructors is not a recognized means of initializing const
fields.

2. ANNOYANCE: chaining constructors allows multiple initialization of const
fields.

3. ANNOYANCE: constructors allow explicit multiple initialization of const
fields.

The work around is to discard constructor chaining in classes requiring dynamic
initialization of const members.  This requires the const member initialization
code to be duplicated in each constructor, C++ style, which is error prone and
produces inelegant code and maintainability issues.

This is a problem (not a show stopper) for a library I'm currently
implementing.  The extra workaround code significantly reduces the readability
of the sample implementation.

Regards,
Garett

------------
module test;
private import std.stdio;

class Foo {
    class Bar { this() { writefln("    Bar.this()"); } }

    const auto Bar bar;

    this() {
        bar = new Bar;
        writefln("    Foo.this()");
    }

    /* 1. This constructor prompts a compiler error
    this(int i) { // missing initializer for const field bar
       this();
       writefln("    Foo.this(%d)", i);
    }
    */

    // 2. This constructor initializes "const" bar twice
    this(float f) { // missing initializer for const field bar
        this();
        bar = new Bar;
        writefln("    Foo.this(%0.1f)", f);
    }

    // 3. Thie constructor explicitly initializes "const" bar more than once
    this(char[] s) {
        this();
        bar = new Bar;
        bar = new Bar; // Should this be an error?
        writefln("    Foo.this(%s)", s);
    }
}

void main() {
    writefln("f...");
    auto Foo f = new Foo(2.f);
    writefln("g...");
    auto Foo g = new Foo("3.0");
}
------------
output:

f...
    Bar.this()
    Foo.this()
    Bar.this()
    Foo.this(2.0)
g...
    Bar.this()
    Foo.this()
    Bar.this()
    Bar.this()
    Foo.this(3.0)
Jan 17 2006
next sibling parent Garett Bass <garettbass studiotekne.com> writes:
Update: Removed an erroneous comment from Foo.this(float f).

------------
module test;
private import std.stdio;

class Foo {
   class Bar { this() { writefln("    Bar.this()"); } }

   const auto Bar bar;

   this() {
       bar = new Bar;
       writefln("    Foo.this()");
   }

   /* 1. This constructor prompts a compiler error
   this(int i) { // missing initializer for const field bar
      this();
      writefln("    Foo.this(%d)", i);
   }
   */

   // 2. This constructor initializes "const" bar twice
   this(float f) {
       this();
       bar = new Bar;
       writefln("    Foo.this(%0.1f)", f);
   }

   // 3. Thie constructor explicitly initializes "const" bar more than once
   this(char[] s) {
       this();
       bar = new Bar;
       bar = new Bar; // Should this be an error?
       writefln("    Foo.this(%s)", s);
   }
}

void main() {
   writefln("f...");
   auto Foo f = new Foo(2.f);
   writefln("g...");
   auto Foo g = new Foo("3.0");
}
------------
output:

f...
   Bar.this()
   Foo.this()
   Bar.this()
   Foo.this(2.0)
g...
   Bar.this()
   Foo.this()
   Bar.this()
   Bar.this()
   Foo.this(3.0)
Jan 19 2006
prev sibling parent Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Garett Bass schrieb am 2006-01-18:
 The code sample below highlights three related issues with constructor
chaining under the current DMD version:

 1. BUG: chaining constructors is not a recognized means of initializing const
fields.
[snip] Added to DStress as http://dstress.kuehne.cn/run/c/const_29_A.d http://dstress.kuehne.cn/run/c/const_29_B.d Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFD3zoU3w+/yD4P9tIRApBfAJ9/2ybTJfWe+cxU7QTLT/IfYQCqOQCdG4hF qMkfel+dqmiz1sMwnDn1WJw= =KEJZ -----END PGP SIGNATURE-----
Jan 31 2006