Would love to override default ctor of struct

Jonathan M Davis newsgroup.d at jmdavisprog.com
Sat Jan 19 11:13:22 UTC 2019


On Saturday, January 19, 2019 3:05:22 AM MST Dru via Digitalmars-d wrote:
> What is the idea behind why we can't define default ctor for
> structs?
>
> In current situation I need to "@disable this()"
> then define a constructor with dummy arguments  (because my
> constructor does not need arguments)
>
> It is a big pain on syntax

Structs in D don't actually have default constructors. Rather, they have a
default value that they're initialized to - namely T.init (where T is the
type name). In fact, all types in D have a default value so that they're
guaranteed to not be garbage if you forget to initialize them with a
specific value. This gets taken advantage of in a number of places. One
obvious one is arrays. The init value can simply be blitted into all of the
elements of the array. A number of features in D are built around that and
really don't work without it.

In fact, if you @disable this() to disable default-initialization, it makes
it so that you can't do a number of things with that type that you can
normally do (e.g. put it in an array), because those language features
require default-initialization. In fact, default values are so critical in
D that a struct with @disable this() still has an init value (e.g. it's used
to initialize the struct before the constructor is called). It's just that
you can't use the struct in places where default initialization is required,
because you told the compiler that you didn't want that to be allowed.
However, code may still explicitly use the init value, and some functions
will use it (e.g move uses it to ensure that the memory that's left behind
after the move isn't in a garbage state). So, while @disable this _can_ be
useful, it tends to just be begging for problems, because D is very much
designed with the idea that everything can be default-initialized, and
@disable this() was only really added as a hack for rare cases where you
really needed to not have something be default-initialized.

If you really need something akin to a default constructor, then the normal
thing to do is to use a factory function, not do something funky like have
dummy arguments. And it may be appropriate in such a situation to @disable
this() so that you don't end up with the object being default-initialized
(theoretically forcing folks to use the factory function), but even then,
there are cases where the init value may still get used, so relying on it
never being used can be problematic.

And yes, sometimes, the fact that you can't have default constructors on
structs in D like you would in C++ can be annoying, but it's a consequence
of the fact that D insists on not having types created with garbage values
(as frequently happens in C/C++), and the rest of the language was then
built with the assumption that everything is default-initialized. So, while
it can be annoying, it does prevent a whole class of bugs that are common in
other languages. All of the various ways around it were added later and are
used at your own risk.

Alternatively, unlike structs, because classes are reference types (and thus
default-initialized to null), they are able to have default constructors.
So, if allocating your objects is fine, then classes may be a better option
for whatever you're trying to do that requires a default constructor. Or
they may not - that would depend on what the code needs to do - but it's
something to consider.

- Jonathan M Davis





More information about the Digitalmars-d mailing list