Jump to page: 1 2
Thread overview
=void in struct definition
Apr 09, 2018
Shachar Shemesh
Apr 09, 2018
Stefan Koch
Apr 09, 2018
Stefan Koch
Apr 09, 2018
jmh530
Apr 09, 2018
Stefan Koch
Apr 09, 2018
Simen Kjærås
Apr 09, 2018
Jonathan M Davis
Apr 11, 2018
Shachar Shemesh
Apr 11, 2018
Jonathan M Davis
Apr 11, 2018
Shachar Shemesh
Apr 11, 2018
Jonathan M Davis
Apr 09, 2018
Johan Engelen
April 09, 2018
struct S {
  int a;
  int[5000] arr = void;
}

void func() {
  S s;
}

During the s initialization, the entire "S" area is initialized, including the member arr which we asked to be = void.

Is this a bug?

Shachar
April 09, 2018
On Monday, 9 April 2018 at 11:06:50 UTC, Shachar Shemesh wrote:
> struct S {
>   int a;
>   int[5000] arr = void;
> }
>
> void func() {
>   S s;
> }
>
> During the s initialization, the entire "S" area is initialized, including the member arr which we asked to be = void.
>
> Is this a bug?
>
> Shachar

Not semantically, but you might consider it a performance bug.
This particular one could be fixed, put I cannot say how messy the details are.
There is potential for code that silently relies on the behavior and would break in very non-obvious ways if we fixed it.
April 09, 2018
On Monday, 9 April 2018 at 11:06:50 UTC, Shachar Shemesh wrote:
> struct S {
>   int a;
>   int[5000] arr = void;
> }
>
> void func() {
>   S s;
> }
>
> During the s initialization, the entire "S" area is initialized, including the member arr which we asked to be = void.
>
> Is this a bug?

https://issues.dlang.org/show_bug.cgi?id=16956

--
  Simen
April 09, 2018
On Monday, April 09, 2018 14:06:50 Shachar Shemesh via Digitalmars-d wrote:
> struct S {
>    int a;
>    int[5000] arr = void;
> }
>
> void func() {
>    S s;
> }
>
> During the s initialization, the entire "S" area is initialized, including the member arr which we asked to be = void.
>
> Is this a bug?

It looks like Andrei created an issue about it as an enhancement request several years ago:

https://issues.dlang.org/show_bug.cgi?id=11331

- Jonathan M Davis

April 09, 2018
On Monday, 9 April 2018 at 11:15:14 UTC, Stefan Koch wrote:
> On Monday, 9 April 2018 at 11:06:50 UTC, Shachar Shemesh wrote:
>> [ ... ]
>> During the s initialization, the entire "S" area is initialized, including the member arr which we asked to be = void.
>>
>> Is this a bug?
>>
>> Shachar
>
> [ ... ] {This could be fixed, but may break code} [ ... ]

So currently on initalizsation we do this:
---
structPtr = cast(StructType*) alloc(structSize);
memcpy(structPtr, StructType.static_struct_initializer, StructType.sizeof);
----
which we could change to
---
structPtr = cast(StructType*) alloc(structSize);
foreach(initializerSegment;StructType.InitializerSegments)
{
    memcpy((cast(void*)structPtr) + initializerSegment.segmentOffset,
           (cast(void*) initializerSegment.segmentPtr),
           initializerSegment.segmentSize);
}
---

This will potentially remove quite a lot of binary bloat since void-members do no longer need to be stored in initializers, and initialization overhead.
In terms of implementation this _should_ be straight-forward but well ... runtime and compiler interaction can be a mess.
April 09, 2018
On 4/9/18 7:06 AM, Shachar Shemesh wrote:
> struct S {
>    int a;
>    int[5000] arr = void;
> }
> 
> void func() {
>    S s;
> }
> 
> During the s initialization, the entire "S" area is initialized, including the member arr which we asked to be = void.
> 
> Is this a bug?

Not technically. It has to initialize `a` to 0. The only way we initialize structs is to copy the whole initializer with memcpy.

It would be possible to leave the "tail" uninitialized, and just store the initializer for the first members that have non-void initializers. But that's not how it works now.

If that were to happen, you'd still have the same issue with things like:

struct S {
   int[5000] arr = void;
   int a;
}

But maybe that's just something we would have to live with.

-Steve
April 09, 2018
On Monday, 9 April 2018 at 11:15:14 UTC, Stefan Koch wrote:
>
> Not semantically, but you might consider it a performance bug.
> This particular one could be fixed, put I cannot say how messy the details are.
> There is potential for code that silently relies on the behavior and would break in very non-obvious ways if we fixed it.

If the fix causes non-obvious breakage, then why not a DIP for an opInit that overrides the default initialization and has the desired new functionality?

Though it would be annoying to have two ways of doing the same thing...
April 09, 2018
On Monday, 9 April 2018 at 14:11:35 UTC, jmh530 wrote:
> On Monday, 9 April 2018 at 11:15:14 UTC, Stefan Koch wrote:
>>
>> Not semantically, but you might consider it a performance bug.
>> This particular one could be fixed, put I cannot say how messy the details are.
>> There is potential for code that silently relies on the behavior and would break in very non-obvious ways if we fixed it.
>
> If the fix causes non-obvious breakage, then why not a DIP for an opInit that overrides the default initialization and has the desired new functionality?
>
> Though it would be annoying to have two ways of doing the same thing...

It's not worth a DIP.
You can write a static initializer function and pass it a GCAlloced pointer.
April 09, 2018
On Monday, 9 April 2018 at 11:06:50 UTC, Shachar Shemesh wrote:
> struct S {
>   int a;
>   int[5000] arr = void;
> }
>
> void func() {
>   S s;
> }
>
> During the s initialization, the entire "S" area is initialized, including the member arr which we asked to be = void.
>
> Is this a bug?

Could be optimized, yes, provided that the spec is updated. We discussed this live at the end of my DConf talk last year, and Walter (in audience) agreed upon the needed spec change. I haven't had/taken the time to work on it yet :(

The optimization of simplifying the initialization isn't too hard. But it is a bit tricky, Johannes wrote down some good points here: https://issues.dlang.org/show_bug.cgi?id=15951
(note the padding bytes issue).  The good news is that there doesn't appear to be any spec about it, so technically there is no language breakage and currently it is an "accepts invalid" bug...

Over dinner me, deadalnix and some others discussed further optimization where emission of the large S.init could be eliminated. We worked out some details, but it's a little harder thing to do.

cheers,
  Johan

April 11, 2018
On 09/04/18 14:22, Jonathan M Davis wrote:
> On Monday, April 09, 2018 14:06:50 Shachar Shemesh via Digitalmars-d wrote:
>> struct S {
>>     int a;
>>     int[5000] arr = void;
>> }
>>
>> void func() {
>>     S s;
>> }
>>
>> During the s initialization, the entire "S" area is initialized,
>> including the member arr which we asked to be = void.
>>
>> Is this a bug?
> 
> It looks like Andrei created an issue about it as an enhancement request
> several years ago:
> 
> https://issues.dlang.org/show_bug.cgi?id=11331
> 
> - Jonathan M Davis
> 

Except that issue talks about default constructed objects. My problem happens also with objects constructed with a constructor:


extern(C) void func(ref S s);

struct S {
    uint a;
    int[5000] arr = void;

    this(uint val) {
        a = val;
    }
}

void main() {
    auto s = S(12);

    // To prevent the optimizer from optimizing s away
    func(s);
}

$ ldc2 -c -O3 -g test.d
$ objdump -S -r test.o | ddemangle > test.s

0000000000000000 <_Dmain>:
    }
}

void main() {
   0:	48 81 ec 28 4e 00 00 	sub    $0x4e28,%rsp
   7:	48 8d 7c 24 04       	lea    0x4(%rsp),%rdi
    auto s = S(12);
   c:	31 f6                	xor    %esi,%esi
   e:	ba 20 4e 00 00       	mov    $0x4e20,%edx
  13:	e8 00 00 00 00       	callq  18 <_Dmain+0x18>
			14: R_X86_64_PLT32	memset-0x4
        a = val;
  18:	c7 04 24 0c 00 00 00 	movl   $0xc,(%rsp)
  1f:	48 89 e7             	mov    %rsp,%rdi

    // To prevent the optimizer from optimizing s away
    func(s);
  22:	e8 00 00 00 00       	callq  27 <_Dmain+0x27>
			23: R_X86_64_PLT32	func-0x4
}
  27:	31 c0                	xor    %eax,%eax
  29:	48 81 c4 28 4e 00 00 	add    $0x4e28,%rsp
  30:	c3                   	retq


Notice the call to memset.

Shachar
« First   ‹ Prev
1 2