struct S {}
class C {
S s;
alias s this;
}
void main() {
auto c = new C;
auto p = cast(void*) c;
}
test.d(10): Error: cannot cast from S to void*
Comment #1 by k.hara.pg — 2011-10-23T05:09:22Z
I think this is right behavior.
In D2, the implicit conversion from class type to void* is disabled. So
auto p = cast(void*) c;
the expression c is transformed to c.s, and cause an error.
----
void main()
{
Object o;
void* p = o;
// test.d(4): Error: cannot implicitly convert expression (o) of type object.Object to void*
}
Comment #2 by timon.gehr — 2011-10-23T08:04:47Z
(In reply to comment #1)
> I think this is right behavior.
> In D2, the implicit conversion from class type to void* is disabled. So
>
> auto p = cast(void*) c;
>
> the expression c is transformed to c.s, and cause an error.
>
auto p = cast(void*) c; works if there is no alias this;. Implicit conversion rules are irrelevant, because this is an explicit conversion. Therefore, I think this is definitely a bug, because adding alias this should never disable features to work, it should only be considered if the code would not compile otherwise.
Comment #3 by luk.wrzosek — 2012-02-14T14:31:59Z
*** Issue 2929 has been marked as a duplicate of this issue. ***
Comment #4 by maximzms — 2013-02-05T07:53:51Z
*** Issue 7985 has been marked as a duplicate of this issue. ***
Comment #5 by verylonglogin.reg — 2013-11-09T05:41:43Z
This is designed behaviour. See documentation improvement Issue 11481.
Comment #6 by jakobovrum — 2013-11-09T05:48:17Z
(In reply to comment #5)
> This is designed behaviour. See documentation improvement Issue 11481.
It makes it impossible to do dynamic casts on class instances with AliasThis. It needs to be changed regardless of whether it's intended or not.
It also makes it impossible to cast some class references to void* while using AliasThis, another important conversion. A workaround for this might be using a union, but I don't think there's a workaround for the dynamic cast.
opCast cannot do the work of these in-built casts.
Comment #7 by schveiguy — 2016-05-17T13:02:56Z
This effectively disables dynamic casting, as Jakob says. Changing to blocker, this is not a trivial bug to work around.
Came up again recently:
https://forum.dlang.org/post/[email protected]
Comment #8 by dfj1esp02 — 2016-05-17T17:09:50Z
Workaround:
---
class A { int a; alias a this; }
class B:A { int b; }
int main()
{
A a = new B;
//B b = cast(B)a;
Object obj = a;
B b = cast(B)obj;
assert(b.b==0);
return 0;
}
---
Comment #9 by schveiguy — 2016-05-17T17:30:47Z
*** Issue 13392 has been marked as a duplicate of this issue. ***
Comment #10 by razvan.nitu1305 — 2018-09-18T20:11:38Z
Comment #11 by razvan.nitu1305 — 2018-10-01T15:42:26Z
*** Issue 3537 has been marked as a duplicate of this issue. ***
Comment #12 by bugzilla — 2018-10-07T09:13:28Z
The problem comes from the idea that having an alias this means that operations not supported by the class get forwarded to the alias this. Since opCast() can override what explicit casts do for a class reference, the alias this needs to be respected (even if it doesn't provide an opCast(), it still can be cast).
The current behavior seems an inevitable consequence of that.
Using alias this in a class may not be a good practice.
Comment #13 by schveiguy — 2018-10-10T15:45:09Z
(In reply to Walter Bright from comment #12)
> The problem comes from the idea that having an alias this means that
> operations not supported by the class get forwarded to the alias this. Since
> opCast() can override what explicit casts do for a class reference, the
> alias this needs to be respected (even if it doesn't provide an opCast(), it
> still can be cast).
But the only mechanism to use dynamic casting is to cast to the requested type. This is expected functionality in the class instance, and in my opinion, default functionality should override any alias this functionality.
Same thing with cast(void *). This is expected functionality.
I don't know of any other mechanism that overrides existing functionality from an alias this'd type, especially when that functionality is not intentionally specified.
For example, I would be really surprised if you had:
struct S
{
int x;
}
struct T
{
int y;
S s;
alias s this;
}
auto t = T(5, S(2));
and this failed because it's trying to call the S implicit constructor instead of the T implicit constructor.
Comment #14 by razvan.nitu1305 — 2018-10-29T12:08:46Z
*** Issue 14331 has been marked as a duplicate of this issue. ***
Comment #15 by github-bugzilla — 2018-11-26T15:54:50Z