On Tuesday, August 5, 2025 6:42:43 PM Mountain Daylight Time Brother Bill via Digitalmars-d-learn wrote: > It doesn't seem like modern D needs the @disable feature. > > If a struct has a user provided constructor, then the default > constructor is removed.
D structs don't really have default constructors. Types in general in D have default initialization, which normally means that variables of that type are initialized with their init value, which is determined at compile time. The exception would be non-static nested structs which also have an implicit context pointer, and those structs get default-initialized with their init value _plus_ their context pointer gets initialized with the address of their outer scope (whereas if you explicitly initialize such a struct with their init value, you get a null context pointer). Either way, there is no constructor involved. The compiler is blitting the type's init value into the object's memory. You can use S() to get the default-initialized value of a struct (which in almost all cases is the same thing is S.init), but either way, it exists whether you declare any constructors for a struct or not. Both S s; and auto s = S(); will give you the default-initialized value of that struct, and that occurs whether the struct has any constructors or not. What you lose when you declare a constructor for a struct is the implicit constructor syntax. That is, if you have something like struct S { int i; string s; bool b; } then syntactically, it's like you have three different constructors, this(int) this(int, string) this(int, string, bool) allowing you to "call" them with expressions such as S(42), S(19, "foo"), and S(27, "bar", false). But the compiler doesn't actually give the struct any constructors (e.g. when you list all of the members of such a struct, no constructors are there). You just get the constructor syntax. And when you declare any normal constructors (as opposed to something like a copy constructor or postblit constructor), then you lose that syntax and can only use the constructors which have been declared. > Are there any cases where @disable is useful in modern D? @disable this(); will disable default initialization for a struct. So, then both S s; and auto s = S(); will fail to compile. You're then forced to explicitly call a constructor to initialize the struct. Similarly, @disable this(this); will disable copying a struct, and @disable void opAssign(S); would disable the assignment operator for a struct. In fact, you can use @disable on any symbol to make it so that it cannot be used. In most cases, you'd just use it to disable something that the compiler would normally automaticaly provide, but what it does in the general case is allow you to have a symbol which will be found via symbol resolution but which can't actually be used. So, you could actually make it so that a struct couldn't be used with a function via UFCS, because it had an @disabled member function with the same name. Similarly, you could declare a variable and then make it unusable with @disable. Whether that's actually useful in practice is debatable, but @disable is a general mechanism which makes it so that a symbol exists but isn't usable. It isn't restricted to a particular set of symbols. But either way, at minumum, it's useful for disabling some of the symbols that the compiler would normally generate automatically, giving you the ability to do things like make a struct uncopyable or unassignable. - Jonathan M Davis