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