Programming in D page 295 - disable default constructor

Jonathan M Davis newsgroup.d at jmdavisprog.com
Tue Feb 10 15:11:32 UTC 2026


On Tuesday, February 10, 2026 6:23:43 AM Mountain Standard Time Brother Bill via Digitalmars-d-learn wrote:
> My question is about the *parameterless* constructor:
> ``` auto a4 = Archive();```
>
> I am unable to define a parameterless constructor for it.
> Is the only alternative to prevent a parameterless construction
> to use ```@disable this();``` ?

Structs in D cannot declare parameterless / default constructors and do not
have default construction. Rather, they're default-initialized (in which
case, the value of the struct's members depends on what the members are
directly initialized to in the struct declaration or to their
default-initialized values if they're not directly given any values). So, if
you have

    Archive a4;

a4 will be default-initialized. What

    auto a4 = Archive();

then does is exactly the same thing except that it's then using explicit
syntax to default-initialize the variable. There really isn't any point in
doing this with a variable declaration. However, where it matters is when
you want to have a default-initialized object without a variable, e.g. with
a function call

    foo(Archive());

The alternative would be

    foo(Archive.init);

However, that actually bypasses default-initialization and uses the struct's
init value. This is the same as default-initialization in almost all cases,
but there are a couple of cases where it's not the same:

1. A non-static struct declared within a function has an additional pointer
pointing to its context. That context pointer is null in the struct's init
value, so with code such as

    void main()
    {
        int i;

        struct Foo
        {
            void func()
            {
                import std.stdio;
                writeln(i);
            }
        }

        Foo a;
        a.func();

        auto b = Foo();
        b.func();

        auto c = Foo.init;
        c.func(); // segfault
    }

the variable which is explicitly initialized with the init value will have a
null context pointer, wereas the default-initialized objects will have valid
context pointers pointing to the function's scope.

2. If a struct has disabled default-initalization with @disable this();,
then Archive.init will be valid code, because the struct's init value is
valid to use, but Archive() will not compile, because default-initialization
has been disabled for the struct. For this reason, most code should not be
using Archive.init and should instead either use Archive() or simply
declare a variable so that it can be default-initialized.

Archive() is not calling any constructors whatsoever. It's giving a
default-initialized Archive object. And so, if you don't want Archive() to
be legal, then you need to declare @disable this(); to explicitly disable
it.

The other wrench in this is that if a struct declares a static opCall, e.g.

    struct Foo
    {
        static int opCall()
        {
            return 42;
        }
    }

then S() would call the struct's static opCall instead of giving the
default-initialized type, so unfortunately, using T() to give a
default-initialized value for structs in generic code doesn't necessarily
work properly. Really, declaring static opCall on struct's probably
shouldn't be legal, so that it can be guaranteed that T() is the
default-initialized value for any struct T, but that corner case wasn't
foreseen when the current design was implemented.

Now, _classes_ can have default / parameterless constructors in D, in which
case, T() would called the implicitly declared default constructor if no
constructor is provided, or a class can have an explicit parameterless
constructor declared (either on its own or in addition to other
constructors), but default constructors have nothing to do with structs in D
even though T() for a struct T is syntactically similar to a default
constructor with classes such as new T().

- Jonathan M Davis






More information about the Digitalmars-d-learn mailing list