Skip to content

Commit d785b7c

Browse files
authored
Fix Issue 14932 - spec does not define what shared attribute does (#3556)
* Fix Issue 14932 - language spec does not define what shared does Normal initialization of shared vars is OK. Add atomicStore, atomicLoad example. Add example showing casting to shared. Mention shared globals use common storage not TLS. * Only mutable globals are thread-local by default
1 parent 31668ea commit d785b7c

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

spec/attribute.dd

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -520,9 +520,7 @@ $(H2 $(LNAME2 shared-storage, Shared Storage Attributes))
520520

521521
$(H3 $(LNAME2 shared, $(D shared) Attribute))
522522

523-
$(P The $(DDSUBLINK spec/const3, shared, $(D shared) attribute) modifies the type from $(D T) to $(D shared(T)),
524-
the same way as $(D const) does.
525-
)
523+
$(P See $(DDSUBLINK spec/const3, shared, $(D shared)).)
526524

527525
$(H3 $(LNAME2 gshared, $(D __gshared) Attribute))
528526

spec/const3.dd

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,24 +577,67 @@ x.atomicOp!"+="(1);
577577
)
578578
$(P $(RED Warning:) An individual read or write operation on shared
579579
data is not an error yet by default. To detect these, use the
580-
`-preview=nosharedaccess` compiler option.)
580+
`-preview=nosharedaccess` compiler option. Normal initialization is
581+
allowed without an error.)
582+
583+
$(SPEC_RUNNABLE_EXAMPLE_RUN
584+
---
585+
import core.atomic;
586+
587+
int y;
588+
shared int x = y; // OK
589+
590+
//x = 5; // write error with preview flag
591+
x.atomicStore(5); // OK
592+
//y = x; // read error with preview flag
593+
y = x.atomicLoad(); // OK
594+
assert(y == 5);
595+
---
596+
)
597+
598+
$(H3 $(LNAME2 shared_cast, Casting))
581599

582600
$(P When working with larger types, manual synchronization
583601
can be used. To do that, `shared` can be cast away for the
584602
duration while mutual exclusion has been established:
585603
)
604+
586605
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
587606
---
588607
struct T;
589608
shared T* x;
609+
590610
synchronized
591611
{
592612
T* p = cast(T*)x;
593613
// operate on `*p`
594614
}
595615
---
596616
)
597-
$(P Lastly, to declare global/static data to be implicitly shared across
617+
618+
$(P An unshared reference can be cast to shared only if the source data
619+
will not be accessed for the lifetime of the cast result.)
620+
621+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
622+
---
623+
class C {}
624+
625+
@trusted shared(C) create()
626+
{
627+
auto c = new C;
628+
// work with c without it escaping
629+
return cast(shared)c; // OK
630+
}
631+
---
632+
)
633+
634+
$(H3 $(LNAME2 shared_global, Shared Global Variables))
635+
636+
$(P Global (or static) shared variables are stored in common storage which
637+
is accessible across threads. Global mutable variables are stored in
638+
thread-local storage by default.)
639+
640+
$(P To declare global/static data to be implicitly shared across
598641
multiple threads without any compiler checks, see $(DDSUBLINK
599642
spec/attribute, gshared, `__gshared`).
600643
)

0 commit comments

Comments
 (0)