Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
October 02, 2020 Whats going on with this? | ||||
---|---|---|---|---|
| ||||
--- import std; import std.stdio; struct Foo { int a = 0, b = 0; this(int[2] vars) { this.a = vars[0]; this.b = vars[1]; // writeln("constructor called"); } } Foo foo = [300,300]; void main() { writeln(foo.a); } --- Compiles and works OK. I cant see anything in the struct docs explaining why that array on the right hand side is automatically converted to a constructor call. Weird thing is if you un-comment the writeln in the constructor it wont compile. You get this... /dlang/dmd/linux/bin64/../../src/phobos/std/stdio.d(4839): Error: variable impl cannot be modified at compile time /dlang/dmd/linux/bin64/../../src/phobos/std/stdio.d(3806): called from here: makeGlobal() /dlang/dmd/linux/bin64/../../src/phobos/std/stdio.d(3896): called from here: trustedStdout() onlineapp.d(13): called from here: writeln("constructor called") onlineapp.d(18): called from here: Foo(0, 0).this([300, 300]) How ever if you move Point foo declaration into the main function it works OK. What exactly is going on? I mean it looks like the Foo is default constructed and then constructed on top with a call to the arary constructor? But why? Why would putting in the writeln cause it to fail? Is it maybe trying to create the foo at compile time? |
October 02, 2020 Re: Whats going on with this? | ||||
---|---|---|---|---|
| ||||
Posted in reply to claptrap | On 10/2/20 7:28 PM, claptrap wrote: > Why would putting in the writeln cause it to fail? Is it maybe trying to create the foo at compile time? > Yes, it is. Any static initialization of static variables happens at compile-time. https://dlang.org/spec/declaration.html#global_static_init -Steve |
October 03, 2020 Re: Whats going on with this? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Saturday, 3 October 2020 at 00:15:02 UTC, Steven Schveighoffer wrote:
> On 10/2/20 7:28 PM, claptrap wrote:
>
>> Why would putting in the writeln cause it to fail? Is it maybe trying to create the foo at compile time?
>>
>
> Yes, it is. Any static initialization of static variables happens at compile-time.
>
> https://dlang.org/spec/declaration.html#global_static_init
>
> -Steve
Ah.. ok, any idea why this works?
Foo foo = [300,300];
Tbh I though I'd defined opAssign to take an array, and was just seeing if it worked, but I hadn't and it seems it's calling the constructor that takes an array, but I cant see in the docs why the above code gets converted to a constructor call.
|
October 03, 2020 Re: Whats going on with this? | ||||
---|---|---|---|---|
| ||||
Posted in reply to claptrap | On Friday, 2 October 2020 at 23:28:04 UTC, claptrap wrote: > I cant see anything in the struct docs explaining why that array on the right hand side is automatically converted to a constructor call. I'm not sure exactly where it is in the docs but that's perfectly normal. Any declaration with initialization of a struct is turned into a construction call if it can. If not, it tries to treat it as a struct literal. I guess this is as close as it comes: https://dlang.org/spec/struct.html#struct-constructor "Struct constructors are used to initialize an instance of a struct when a more complex construction is needed than is allowed by static initialization or a struct literal. " Which sends you back up here: https://dlang.org/spec/struct.html#static_struct_init showing the = syntax. opAssign is only used AFTER the struct has already been declared. |
October 03, 2020 Re: Whats going on with this? | ||||
---|---|---|---|---|
| ||||
Posted in reply to claptrap | On 10/3/20 6:52 AM, claptrap wrote:
> On Saturday, 3 October 2020 at 00:15:02 UTC, Steven Schveighoffer wrote:
>> On 10/2/20 7:28 PM, claptrap wrote:
>>
>>> Why would putting in the writeln cause it to fail? Is it maybe trying to create the foo at compile time?
>>>
>>
>> Yes, it is. Any static initialization of static variables happens at compile-time.
>>
>> https://dlang.org/spec/declaration.html#global_static_init
>>
>
> Ah.. ok, any idea why this works?
>
> Foo foo = [300,300];
Yeah, it's calling the constructor. I agree with Adam, there's nothing in the spec that talks about this that I can find.
-Steve
|
October 03, 2020 Re: Whats going on with this? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer Attachments:
| On Sat, Oct 3, 2020 at 4:45 PM Steven Schveighoffer via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > On 10/3/20 6:52 AM, claptrap wrote: > > On Saturday, 3 October 2020 at 00:15:02 UTC, Steven Schveighoffer wrote: > >> On 10/2/20 7:28 PM, claptrap wrote: > >> > >>> Why would putting in the writeln cause it to fail? Is it maybe trying to create the foo at compile time? > >>> > >> > >> Yes, it is. Any static initialization of static variables happens at compile-time. > >> > >> https://dlang.org/spec/declaration.html#global_static_init > >> > > > > Ah.. ok, any idea why this works? > > > > Foo foo = [300,300]; > > Yeah, it's calling the constructor. I agree with Adam, there's nothing in the spec that talks about this that I can find. > > -Steve > I would say it is here you just need to read it carefully: https://dlang.org/spec/struct.html#static_struct_init |
October 03, 2020 Re: Whats going on with this? | ||||
---|---|---|---|---|
| ||||
Attachments:
| On Sat, Oct 3, 2020 at 10:40 PM Daniel Kozak <kozzi11@gmail.com> wrote: > I would say it is here you just need to read it carefully: > > https://dlang.org/spec/struct.html#static_struct_init > > For case specification is change I will paste it here: ''' If a StructInitializer is supplied, the fields are initialized by the StructMemberInitializer syntax. StructMemberInitializers with the Identifier : NonVoidInitializer syntax may be appear in any order, where Identifier is the field identifier. StructMemberInitializers with the NonVoidInitializer syntax appear in the lexical order of the fields in the StructDeclaration. ''' And StructMemberInitializer is defined as: ''' StructMemberInitializer: NonVoidInitializer Identifier : NonVoidInitializer ''' And NonVoidInitializer is defined as: ''' NonVoidInitializer: ExpInitializer ArrayInitializer StructInitializer ''' And as you can see there is ArrayInitializer And there is definition of Array literals here https://dlang.org/spec/expression.html#array_literals and in section 2. there is this text: ''' By default, an array literal is typed as a dynamic array, but the element count is known at compile time. So all array literals can be implicitly converted to static array types. ''' |
October 03, 2020 Re: Whats going on with this? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Kozak | On 10/3/20 4:46 PM, Daniel Kozak wrote:
>
>
> On Sat, Oct 3, 2020 at 10:40 PM Daniel Kozak <kozzi11@gmail.com <mailto:kozzi11@gmail.com>> wrote:
>
> I would say it is here you just need to read it carefully:
>
> https://dlang.org/spec/struct.html#static_struct_init
>
>
> For case specification is change I will paste it here:
> '''
> If a StructInitializer is supplied, the fields are initialized by the StructMemberInitializer syntax. StructMemberInitializers with the Identifier : NonVoidInitializer syntax may be appear in any order, where Identifier is the field identifier. StructMemberInitializers with the NonVoidInitializer syntax appear in the lexical order of the fields in the StructDeclaration.
> '''
>
> And StructMemberInitializer is defined as:
>
> '''
> StructMemberInitializer:
> NonVoidInitializer
> Identifier : NonVoidInitializer
> '''
>
> And NonVoidInitializer is defined as:
>
> '''
> NonVoidInitializer:
> ExpInitializer
> ArrayInitializer
> StructInitializer
> '''
>
> And as you can see there is ArrayInitializer
>
> And there is definition of Array literals here
> https://dlang.org/spec/expression.html#array_literals
>
> and in section 2. there is this text:
>
> '''
> By default, an array literal is typed as a dynamic array, but the element count is known at compile time. So all array literals can be implicitly converted to static array types.
> '''
"StructMemberInitializers with the NonVoidInitializer syntax appear in the lexical order of the fields in the StructDeclaration" seems to suggest it will not call the constructor, but instead initialize the fields according to the list.
The fields are not a static array, so clearly it is calling the constructor, and not initializing the fields.
I really don't think this case is in the spec.
But I know it works, for instance:
Variant v = anything;
If this required an explicit Variant constructor, it would be quite annoying.
-Steve
|
October 04, 2020 Re: Whats going on with this? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer Attachments:
| On Sat, Oct 3, 2020 at 11:30 PM Steven Schveighoffer via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > > > "StructMemberInitializers with the NonVoidInitializer syntax appear in the lexical order of the fields in the StructDeclaration" seems to suggest it will not call the constructor, but instead initialize the fields according to the list. > > The fields are not a static array, so clearly it is calling the constructor, and not initializing the fields. > > I really don't think this case is in the spec. > > But I know it works, for instance: > > Variant v = anything; > > If this required an explicit Variant constructor, it would be quite annoying. > > -Steve > Yes you are right |
Copyright © 1999-2021 by the D Language Foundation