getOpt with shared

Jonathan M Davis newsgroup.d at jmdavisprog.com
Fri May 11 18:49:08 UTC 2018


On Friday, May 11, 2018 14:31:17 Steven Schveighoffer via Digitalmars-d-
learn wrote:
> On 5/11/18 1:25 PM, Danny Arends wrote:
> > Hey all,
> >
> > I have been working on creating a multi-threaded application, so I have
> > a shared configuration object which hold several command line parameters
> > (which I fill using getopt).
> >
> > The problem is that I get deprecation warnings when trying to set
> > numerical values:
> >
> > /usr/include/dmd/phobos/std/getopt.d(895,36): Deprecation:
> > read-modify-write operations are not allowed for shared variables. Use
> > core.atomic.atomicOp!"+="(*receiver, 1) instead.
> >
> > using getopt with a shared object and boolean values seems completely
> > broken:
> >
> > /usr/include/dmd/phobos/std/getopt.d(895,34): Error: operation not
> > allowed on bool *receiver += 1
> > /usr/include/dmd/phobos/std/getopt.d(751,46): Error: template instance
> > `std.getopt.handleOption!(shared(bool)*)` error instantiating
> > /usr/include/dmd/phobos/std/getopt.d(435,15):        6 recursive
> > instantiations from here: getoptImpl!(string, shared(string)*, string,
> > shared(string)*, string, shared(VSync)*, string, shared(ulong)*, string,
> > shared(bool)*, string, shared(Verbose)*)
> >
> > Is getopt not supposed to be used with shared structs ?
>
> No, just fill in a local copy, and then copy it to the shared location.
>
> In the case where all you want is read-only access to the data, build it
> once and then cast to immutable:
>
> immutable Config config;
>
> void main(string[] args)
> {
>     Config localConfig;
>     getopt(...); // fill in localConfig
>     // VERY IMPORTANT, only do this ONCE, and don't use it before this
> line *(cast()&config) = localConfig;
> }
>
> It should now be accessible from all threads.
>
> Normally, this is not encouraged (casting away immutable), but the
> compiler gets that an immutable global is allowed to be initialized once
> (in fact, you can do this without casting inside shared static
> constructors).

Except that because this is done outside of a shared static constructor,
you're technically mutating immutable data. This _should_ work, but it is
violating the type system, and technically, the compiler is allowed to
assume that config is Config.init everywhere. In practice, I wouldn't expect
a problem, but because it's violating the type system, all bets are off.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list