www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Classes and disable this()

reply "fra" <a b.it> writes:
I just realized that you cannot define a disabled "default" 
constructor for classes: writing code like this will give a 
linker error

class Something
{
Feb 08 2015
parent reply "fra" <a b.it> writes:
On Sunday, 8 February 2015 at 16:22:36 UTC, fra wrote:
Missclick... Anywya:
class Something
{
     disable this();
    this(int i) {}
}

produces an undefined reference error.

I guess it has to do with classes implicitly inheriting from 
Object, and Object defining a this(), and  disable telling the 
compiler not to produce code for the given function.

However making it a compiler error would be far, far better then 
getting the linker error. In my case, the mangled name was 100% 
unintelligible (the usual "_ctor" was nowhere to be found, 
probably due to the class name being so long that it was getting 
shortened in some way)
Feb 08 2015
next sibling parent "Rene Zwanenburg" <renezwanenburg gmail.com> writes:
On Sunday, 8 February 2015 at 16:28:21 UTC, fra wrote:
 On Sunday, 8 February 2015 at 16:22:36 UTC, fra wrote:
 Missclick... Anywya:
 class Something
 {
     disable this();
    this(int i) {}
 }

 produces an undefined reference error.

 I guess it has to do with classes implicitly inheriting from 
 Object, and Object defining a this(), and  disable telling the 
 compiler not to produce code for the given function.

 However making it a compiler error would be far, far better 
 then getting the linker error. In my case, the mangled name was 
 100% unintelligible (the usual "_ctor" was nowhere to be found, 
 probably due to the class name being so long that it was 
 getting shortened in some way)
No need to use disable this(); A default constructor will only be generated when you don't define a constructor yourself.
Feb 08 2015
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
fra:

 However making it a compiler error would be far, far better
I think this can be filed in Bugzilla as diagnostic enhancement: class Foo { disable this(); this(int i) {} } void main() {} Bye, bearophile
Feb 08 2015
next sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Sunday, February 08, 2015 17:51:09 bearophile via Digitalmars-d-learn wrote:
 fra:

 However making it a compiler error would be far, far better
I think this can be filed in Bugzilla as diagnostic enhancement: class Foo { disable this(); this(int i) {} } void main() {}
The compiler should probably just give you an error telling you that disabling the default constructor on classes is illegal. And since no default constructor is automatically declared if you declare another constructor, there isn't even any point in disabling the default constructor (which is probably why no one has been complaining about this). disable this() only makes sense on structs. - Jonathan M Davis
Feb 08 2015
next sibling parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Sunday, 8 February 2015 at 19:57:28 UTC, Jonathan M Davis 
wrote:
 On Sunday, February 08, 2015 17:51:09 bearophile via 
 Digitalmars-d-learn wrote:
 fra:

 However making it a compiler error would be far, far better
I think this can be filed in Bugzilla as diagnostic enhancement: class Foo { disable this(); this(int i) {} } void main() {}
The compiler should probably just give you an error telling you that disabling the default constructor on classes is illegal. And since no default constructor is automatically declared if you declare another constructor, there isn't even any point in disabling the default constructor (which is probably why no one has been complaining about this). disable this() only makes sense on structs.
Alternatively, it could be accepted (and a no-op) if another constructor is defined, but an error if not.
Feb 09 2015
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 2/8/15 2:57 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
 On Sunday, February 08, 2015 17:51:09 bearophile via Digitalmars-d-learn wrote:
 fra:

 However making it a compiler error would be far, far better
I think this can be filed in Bugzilla as diagnostic enhancement: class Foo { disable this(); this(int i) {} } void main() {}
The compiler should probably just give you an error telling you that disabling the default constructor on classes is illegal. And since no default constructor is automatically declared if you declare another constructor, there isn't even any point in disabling the default constructor (which is probably why no one has been complaining about this). disable this() only makes sense on structs.
Why? I think it's perfectly acceptable. What should be illegal is if you extend Foo and don't disable this on the derivative. -Steve
Feb 09 2015
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Monday, February 09, 2015 13:29:22 Steven Schveighoffer via
Digitalmars-d-learn wrote:
 On 2/8/15 2:57 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
 On Sunday, February 08, 2015 17:51:09 bearophile via Digitalmars-d-learn wrote:
 fra:

 However making it a compiler error would be far, far better
I think this can be filed in Bugzilla as diagnostic enhancement: class Foo { disable this(); this(int i) {} } void main() {}
The compiler should probably just give you an error telling you that disabling the default constructor on classes is illegal. And since no default constructor is automatically declared if you declare another constructor, there isn't even any point in disabling the default constructor (which is probably why no one has been complaining about this). disable this() only makes sense on structs.
Why? I think it's perfectly acceptable. What should be illegal is if you extend Foo and don't disable this on the derivative.
Why would it we even allow it? What benefit is there? It's meaningless. disable this(); is for disabling the init property on structs. Classes themselves have no init values - and their references have null as their init value. The default constructor already follows sensible rules where it's not generated if another constructor is declared, and derived classes have to call a base class constructor if the base class doesn't have a default constructor. - Jonathan M Davis
Feb 09 2015
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 2/9/15 3:15 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
 On Monday, February 09, 2015 13:29:22 Steven Schveighoffer via
Digitalmars-d-learn wrote:
 On 2/8/15 2:57 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
 On Sunday, February 08, 2015 17:51:09 bearophile via Digitalmars-d-learn wrote:
 fra:

 However making it a compiler error would be far, far better
I think this can be filed in Bugzilla as diagnostic enhancement: class Foo { disable this(); this(int i) {} } void main() {}
The compiler should probably just give you an error telling you that disabling the default constructor on classes is illegal. And since no default constructor is automatically declared if you declare another constructor, there isn't even any point in disabling the default constructor (which is probably why no one has been complaining about this). disable this() only makes sense on structs.
Why? I think it's perfectly acceptable. What should be illegal is if you extend Foo and don't disable this on the derivative.
Why would it we even allow it? What benefit is there? It's meaningless. disable this(); is for disabling the init property on structs. Classes themselves have no init values - and their references have null as their init value. The default constructor already follows sensible rules where it's not generated if another constructor is declared, and derived classes have to call a base class constructor if the base class doesn't have a default constructor.
Well, if I do this: class C {} I can do this: new C(); Mechanisms to disable this are kind of awkward. I can define this() as private, but that doesn't help for intra-module calls. static class C doesn't work. It really is only useful in the case where you don't want to define a constructor. Which probably means -- you don't want to use a class anyway ;) But for completeness, it seems like I should be able to have the option of disabling something the compiler does by default. Even if it's next to useless. -Steve
Feb 09 2015
parent Jonathan M Davis via Digitalmars-d-learn writes:
On Monday, February 09, 2015 15:25:14 Steven Schveighoffer via
Digitalmars-d-learn wrote:
 Well, if I do this:

 class C {}

 I can do this:

 new C();

 Mechanisms to disable this are kind of awkward. I can define this() as
 private, but that doesn't help for intra-module calls.

 static class C doesn't work.

 It really is only useful in the case where you don't want to define a
 constructor. Which probably means -- you don't want to use a class anyway ;)

 But for completeness, it seems like I should be able to have the option
 of disabling something the compiler does by default. Even if it's next
 to useless.
I suppose that it makes sense if you want to make it so that the class can't be constructed (and actually, now that I look at it, that's what std.datetime.Clock does), but if another constructor has been declared, then it should be probably be disallowed at compile time - especially if it's resulting in a linker error. - Jonathan M Davis
Feb 10 2015
prev sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Monday, 9 February 2015 at 20:15:28 UTC, Jonathan M Davis 
wrote:
 On Monday, February 09, 2015 13:29:22 Steven Schveighoffer via 
 Digitalmars-d-learn wrote:
 On 2/8/15 2:57 PM, Jonathan M Davis via Digitalmars-d-learn 
 wrote:
 On Sunday, February 08, 2015 17:51:09 bearophile via 
 Digitalmars-d-learn wrote:
 fra:

 However making it a compiler error would be far, far better
I think this can be filed in Bugzilla as diagnostic enhancement: class Foo { disable this(); this(int i) {} } void main() {}
The compiler should probably just give you an error telling you that disabling the default constructor on classes is illegal. And since no default constructor is automatically declared if you declare another constructor, there isn't even any point in disabling the default constructor (which is probably why no one has been complaining about this). disable this() only makes sense on structs.
Why? I think it's perfectly acceptable. What should be illegal is if you extend Foo and don't disable this on the derivative.
Why would it we even allow it? What benefit is there? It's meaningless. disable this(); is for disabling the init property on structs. Classes themselves have no init values - and their references have null as their init value.
No, ` disable this()` does _not_ disable the init property on structs. It disables default, i.e. argument-less construction. Which is analogous to `new MyClass()`. It makes perfect sense to disable argument-less construction in classes, just like with structs. (They are of course different, in that struct default constructors don't "do" anything, but that's not relevant here.)
 The default constructor already follows sensible rules where 
 it's not
 generated if another constructor is declared, and derived 
 classes have to
 call a base class constructor if the base class doesn't have a 
 default
 constructor.
Therefore ` disable this()` is redundant in that case, but still meaningful.
Feb 10 2015
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, February 10, 2015 11:16:21 via Digitalmars-d-learn wrote:
 On Monday, 9 February 2015 at 20:15:28 UTC, Jonathan M Davis
 Why would it we even allow it? What benefit is there? It's
 meaningless.
  disable this(); is for disabling the init property on structs.
 Classes
 themselves have no init values - and their references have null
 as their
 init value.
No, ` disable this()` does _not_ disable the init property on structs. It disables default, i.e. argument-less construction. Which is analogous to `new MyClass()`. It makes perfect sense to disable argument-less construction in classes, just like with structs. (They are of course different, in that struct default constructors don't "do" anything, but that's not relevant here.)
Well, then that's a change. It used to be that disable this() completely disabled the init property. So, I guess now it just disables its implicit use, which probably screws up its use for stuff like a NonNullable (which is why it exists in the first place), but having types without an init property definitely would make things nasty with generic code (which is where we sat for a while, I believe). - Jonathan M Davis
Feb 10 2015
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 2/10/15 12:15 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
 On Tuesday, February 10, 2015 11:16:21 via Digitalmars-d-learn wrote:
 On Monday, 9 February 2015 at 20:15:28 UTC, Jonathan M Davis
 Why would it we even allow it? What benefit is there? It's
 meaningless.
  disable this(); is for disabling the init property on structs.
 Classes
 themselves have no init values - and their references have null
 as their
 init value.
No, ` disable this()` does _not_ disable the init property on structs. It disables default, i.e. argument-less construction. Which is analogous to `new MyClass()`. It makes perfect sense to disable argument-less construction in classes, just like with structs. (They are of course different, in that struct default constructors don't "do" anything, but that's not relevant here.)
Well, then that's a change. It used to be that disable this() completely disabled the init property. So, I guess now it just disables its implicit use, which probably screws up its use for stuff like a NonNullable (which is why it exists in the first place), but having types without an init property definitely would make things nasty with generic code (which is where we sat for a while, I believe).
No, it's not a change. You could always do: S s = S.init; What the feature disabled is this: S s; -Steve
Feb 10 2015
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
 I think this can be filed in Bugzilla as diagnostic enhancement:


 class Foo {
      disable this();
     this(int i) {}
 }
 void main() {}
https://issues.dlang.org/show_bug.cgi?id=14163 Bye, bearophile
Feb 10 2015