Unintuitive behavior with shared classes & template member functions; is this intended?

Jaime benjamin.i.mccann at gmail.com
Fri Jan 14 23:10:49 UTC 2022


Some code that produces the strange behavior I'm seeing:

```d
shared class MyClass {
     this() {}
     this(As...)(As args) if (As.length > 0) {}
}

void main() {
     pragma(msg, typeof(new MyClass));
     pragma(msg, typeof(new MyClass(1, 2, 3, "hello world")));
     pragma(msg, typeof(new shared(MyClass)));
     pragma(msg, typeof(new shared(MyClass)(1, 2, 3, "hello 
world")));
}
```

Expected output of compilation:

```
shared(MyClass)
shared(MyClass)
shared(MyClass)
shared(MyClass)
```

Actual output of compilation:

```
test.d(7): Error: none of the overloads of `__ctor` are callable 
using a non-shared object, candidates are:
test.d(2):        `test.MyClass.this()`
test.d(3):        `__ctor(As...)(As args)`
   with `As = ()`
   must satisfy the following constraint:
`       As.length > 0`
_error_
MyClass
shared(MyClass)
test.d(10): Error: none of the overloads of `this` are callable 
using argument types `(int, int, int, string) shared`, candidates 
are:
test.d(2):        `test.MyClass.this()`
test.d(3):        `__ctor(As...)(As args)`
_error_
```

Compiler version: 64-bit, v2.096.1, on Linux

What this seems to illustrate is that template member functions 
of a shared class are not implicitly shared. Alarmingly, this 
example illustrates this is true specifically for template 
constructors, meaning if a shared class has a template 
constructor that's not explicitly shared, it's possible to 
construct a non-shared instance of the shared class.

Why does this happen? Is it intended behavior? I'm still somewhat 
new to D, so I'm not prepared to submit this as an issue quite 
yet; for all I know, there might be a good reason it works this 
way.

This confusing problem really bit me in the patootie in a 
personal project earlier. Fortunately, although it was difficult 
to guess what was going on, once I did, it was an easy fix: 
namely, a template member function explicitly marked as shared 
is, of course, compiled as shared, as desired.


More information about the Digitalmars-d-learn mailing list