Thread overview
How to define a constructor in a struct?
Aug 05, 2012
Minas Mina
Aug 05, 2012
Adam D. Ruppe
Aug 05, 2012
Minas Mina
Aug 05, 2012
Adam D. Ruppe
Aug 05, 2012
Minas Mina
Aug 05, 2012
Jacob Carlborg
Aug 05, 2012
Jonathan M Davis
August 05, 2012
I want to make a struct that defines a constructor:

struct Point
{
	this()
	{
	}
}


However I get a compiler error:
"constructor main.Point.this default constructor for structs only allowed with @disable and no body"

I wrote a @disable next to it but same error. I don't understand what the "no body" part means.
August 05, 2012
On Sunday, 5 August 2012 at 16:05:54 UTC, Minas Mina wrote:
> I want to make a struct that defines a constructor:

You can't quite do it. A D struct is supposed to always be trivial to initialize. You can, however, do a static opCall(), constructors that take parameters, and/or disable default construction, forcing the user to use one of those other ones.

> I wrote a @disable next to it but same error. I don't understand what the "no body" part means.

You'd write it

@disable this();


What this does is say this struct can't be default defined - the user would have to initialize it using one of its other constructors.

For example:


struct Test {
   @disable this(); // this makes it so Test t; won't work - you have to use a constructor of some sort

   this(int num) {
        // construct it using the number
   }

   // static opCall makes Test() work when you spell it out
   static Test opCall() {
        Test t = Test(1);
        return t;
   }
}

void main() {
	//Test t; // compile error - default construction is diabled

	Test t = Test(); // uses opCall

	Test t2 = Test(5); // uses the constructor with an int param
}
August 05, 2012
Thank you. Is it the way it is to have compatibility with C structs?
August 05, 2012
On Sunday, 5 August 2012 at 16:30:48 UTC, Minas Mina wrote:
> Thank you. Is it the way it is to have compatibility with C structs?

I'm not sure... I think so in part, but I think another part of it is to make sure that struct constructors can't bring a hidden cost to generic code.
August 05, 2012
On Sunday, 5 August 2012 at 16:42:16 UTC, Adam D. Ruppe wrote:
> On Sunday, 5 August 2012 at 16:30:48 UTC, Minas Mina wrote:
>> Thank you. Is it the way it is to have compatibility with C structs?
>
> I'm not sure... I think so in part, but I think another part of it is to make sure that struct constructors can't bring a hidden cost to generic code.

I see. Thank you a lot for your help!
August 05, 2012
On 2012-08-05 18:30, Minas Mina wrote:
> Thank you. Is it the way it is to have compatibility with C structs?

No, I don't think so. If I recall correctly it has something to do with the .init property and the compiler need to know the initialization code of the sturct at compile time.

-- 
/Jacob Carlborg
August 05, 2012
On Sunday, August 05, 2012 19:28:30 Jacob Carlborg wrote:
> On 2012-08-05 18:30, Minas Mina wrote:
> > Thank you. Is it the way it is to have compatibility with C structs?
> 
> No, I don't think so. If I recall correctly it has something to do with the .init property and the compiler need to know the initialization code of the sturct at compile time.

Exactly. Every type in D must have an init value. So when you do

T value;

or

T[10] array;

the data isn't garbage. That's straightforward enough for the built-in types (0 for integral types, NaN for floats, false for bool, etc.) and pointers and references are null, so it's not a problem for classes either. But for structs - which normally go on the stack - it's more problematic. init must be the state of the whole struct, and it needs to be known at compile time. So, having an arbitrary default constructor just doesn't work. So, you can't have a default constructor on a struct. The result of one design decision (making it so that no variables in D are undefined by default) forces another (no default constructors for structs).

Declaring a static opCall is the typical way to get around it, and if you need it so that you're struct can't be default-initialized, you disable it

@disable this();

which makes it so that that struct has no init value and cannot be used in any situation where an init value is required (which carries its own annoyances, but it's an option). However, I believe that @disabling this is very broken at the moment unfortunately, and it doesn't actually end up disabling much.

- Jonathan M Davis