On Tuesday, 22 March 2016 at 21:32:24 UTC, Alex Parrill wrote:

As long as there's no race conditions in the initial creation of the mutex, it shouldn't matter, even though it does internally mutate the object, because it's transparent to developers (unless you're going out of your way to access the internal __monitor field).

Internally, the compiler breaks a language guarantee: it allows passing an immutable Object to a function as mutable argument. The synchronization object is passed to _d_monitorenter in druntime.

An optimizer may use the immutability information, leading to troubles.
```
import std.stdio : writeln;
interface Foo {}
void main() {
    writeln(cast(size_t) typeid(Foo).__monitor);
    synchronized(typeid(Foo)) {   }
    writeln(cast(size_t) typeid(Foo).__monitor);
}
```
This prints two zeros for `ldc2 -O3 -run`. (typeid(Foo) is immutable in LDC) So the optimizer deduces the __monitor pointer is still null, even though it no longer is after the synchronized statement.

What exactly is bugged about the typeid example under LDC?

See https://github.com/ldc-developers/ldc/issues/1377
It is an example proving that synchronizing on an immutable object is dangerous.

Reply via email to