On Monday, 8 August 2022 at 20:36:34 UTC, Steven Schveighoffer wrote:
[...]
> shared gives you a sense that the language is helping you prevent problems. Again, if C isn't playing ball, this is a lie.
The C side is playing ball, by whatever rules the C library chooses.
shared
(with -preview=nosharedaccess
) prevents you from going on the field. Can't unwittingly commit a foul. Can't hurt yourself. You can tell the compiler with a cast that (1) you're sure you want to play, and (2) you're going to play by the rules of the C side (whatever they are).
__gshared
just lets you run on the field. Don't know the rules? The compiler doesn't care. Have fun breaking your legs.
[...]
> Consider if the proper way to use such a variable is to call properlyUse(int *)
, it won't accept a shared int *
. Now you are doubly-sure to mess up using it specifically because it's marked shared
.
With __gshared
:
extern(C) extern __gshared int x;
void fun() { x = 42; } /* compiles, race condition */
I never even realize that I'm doing something dangerous, because my first naive attempt passes compilation and seems to work fine.
With shared
(and -preview=nosharedaccess
):
extern(C) extern shared int x;
void fun() { x = 42; } /* error */
If I remember to check the documentation, I might find out about properlyUse
. As you suggest, I come up with this:
extern(C) extern shared int x;
void fun() { properlyUse(&x, 42); } /* still error because `shared` */
I'm forced to think more about thread-safety. I figure that it's ok to cast away shared
in this case, because I'm calling the thread-safe properlyUse
function. So:
extern(C) extern shared int x;
void fun() { properlyUse(cast(int*) &x, 42); } /* compiles, is correct */
I don't believe that people are more likely to get that right with __gshared
. The call to properlyUse
might look nicer without the cast, but I'm not buying that people remember to use the function without the compiler yelling at them.
Even if they get it right the first time, they're bound to slip up as time progresses. When simple, incorrect code compiles, it will surely make its way into the source files.
Thread-safety is hard to get right. We need every help we can get from the compiler. __gshared
provides zero help. shared
at least highlights the interesting spots.