getOpt with shared

Steven Schveighoffer schveiguy at yahoo.com
Fri May 11 18:31:17 UTC 2018


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).

-Steve


More information about the Digitalmars-d-learn mailing list