August 22, 2017
On Tuesday, 22 August 2017 at 15:52:48 UTC, Kagamin wrote:
> On Tuesday, 22 August 2017 at 14:53:21 UTC, Moritz Maxeiner wrote:
>> There is a bug [1] - as others have pointed out - that the static array isn't stored in TLS, but in global storage, however, but that doesn't apply in this single threaded case.
>
> The initializer is copied from typeinfo, that can't refer to TLS data.

Which means it isn't easily fixable (or even feasible). I'd still consider it a loophole in the type system right now as it allows declaring global data mutably shared between threads without `shared` or `__gshared` (the latter of which couldn't be applied here, though).
I'd argue that - as new in this case doesn't allocate on the heap, but in the resulting application's appropriate segments) - it should work like this (from a language semantics standpoint):

---

class Test
{
    shared(ubyte)[] buf = new shared(ubyte)[1000]; // classic global storage, instances in all threads refer to the same static array
}

class Test
{
    ubyte[] buf = new ubyte[1000]; // thread local storage, instances in the same thread refer to the same static array
}
---
August 22, 2017
On Tue, Aug 22, 2017 at 04:28:43PM +0000, Moritz Maxeiner via Digitalmars-d wrote: [...]
> I'd argue that - as new in this case doesn't allocate on the heap, but in the resulting application's appropriate segments) - it should work like this (from a language semantics standpoint):
> 
> ---
> 
> class Test
> {
>     shared(ubyte)[] buf = new shared(ubyte)[1000]; // classic global
> storage, instances in all threads refer to the same static array
> }
> 
> class Test
> {
>     ubyte[] buf = new ubyte[1000]; // thread local storage, instances in the
> same thread refer to the same static array
> }
> ---

Sounds like a good idea.  Please file this in bugzilla (if it isn't already) so that it doesn't get lost in the ether.


T

-- 
Two wrongs don't make a right; but three rights do make a left...
August 23, 2017
On Tuesday, 22 August 2017 at 16:28:43 UTC, Moritz Maxeiner wrote:
> class Test
> {
>     ubyte[] buf = new ubyte[1000]; // thread local storage, instances in the same thread refer to the same static array
> }

Dynamic initialization is done by constructor:

class Test
{
    static ubyte[1000] s;
    ubyte[] buf;
    this()
    {
        buf=s;
    }
}

It's also unambiguous as to how it works.
August 23, 2017
On Wednesday, 23 August 2017 at 09:12:19 UTC, Kagamin wrote:
> On Tuesday, 22 August 2017 at 16:28:43 UTC, Moritz Maxeiner wrote:
>> class Test
>> {
>>     ubyte[] buf = new ubyte[1000]; // thread local storage, instances in the same thread refer to the same static array
>> }
>
> Dynamic initialization is done by constructor:
>
> [...]
>
> It's also unambiguous as to how it works.

I am aware, as I have pointed out the same in the above, but the post you quote is explicitly not about dynamic initialization (i.e. the result of new points into the heap), but about static initialization (the result of new points into sections of the binary format).
Specifically, it's about static initialization done for variables put into classic global storage (e.g. ELF sections .data/.bss) and variables put into thread local storage (e.g. ELF sections .tdata/.tbss).
1 2
Next ›   Last »