On Sunday, 23 December 2018 at 14:07:04 UTC, Johannes Loher wrote:
I recently played around with atomic operations. While doing
so, I noticed a problem with the interaction of interfaces and
cas. Consider the following program:
```
import core.atomic;
import std.stdio;
interface TestInterface
{
}
class TestClass : TestInterface
{
}
void main()
{
shared TestInterface testInterface = new shared TestClass;
cas(&testInterface, testInterface, new shared
TestClass).writeln;
writeln(typeid(testInterface));
}
```
(https://run.dlang.io/is/9P7PAb)
The types of the 2nd and 3rd arguments of `cas` do not have to be
the same, and aren't in your case. I think what's happening is
that you are overwriting `testInterface` with a pointer to a
TestClass which is not a valid TestInterface pointer. And then
the program does something invalid because, well, you enter UB
land.
Fixed by:
```
cas(&testInterface, testInterface, cast(shared(TestInterface))
new shared TestClass).writeln;
```
Note the cast!
Whether this is a bug in `cas` or not, I don't know. The `cas`
template checks whether the 3rd can be assigned to the 1st
argument (`*here = writeThis;`) which indeed compiles _with_ an
automatic conversion. But then the implementation of `cas` does
not do any automatic conversions (casts to `void*`). Hence the
problem you are seeing.
-Johan