Thread overview
BUG: Constructor chaining and const member intialization
Jan 18, 2006
Garett Bass
Jan 19, 2006
Garett Bass
Jan 31, 2006
Thomas Kuehne
January 18, 2006
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)
January 19, 2006
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)
January 31, 2006
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