Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
March 13, 2017 Recursive template instantiation | ||||
---|---|---|---|---|
| ||||
I'm pretty sure that this code should compile (https://dpaste.dzfl.pl/cf1e1ee6ef4b): struct A(T) { ~this() { char[T.sizeof] data; } } struct B(T) { A!T foo; } struct C { B!C bar; } void main() { C c; } But it doesn't: /d300/f416.d(3): Error: struct f416.C no size because of forward reference /d300/f416.d(12): Error: template instance f416.B!(C) error instantiating Notice that the same C++ code compiles without problems: template<typename T> struct A { ~A() { char data[sizeof(T)]; } }; template<typename T> struct B { A<T> foo; }; struct C { B<C> bar; }; int main() { C c; } A simple recursion is compiled successfully (https://dpaste.dzfl.pl/5a8ff73bfa88): struct A(T) { ~this() { char[T.sizeof] data; } } struct C { A!C bar; } void main() { C c; } |
March 13, 2017 Re: Recursive template instantiation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | Is this a bug? |
March 13, 2017 Re: Recursive template instantiation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On Monday, 13 March 2017 at 22:05:24 UTC, Jack Applegame wrote:
> Is this a bug?
No it's not
struct C
{
B!C;
}
is an error.
Howto compute C ? <------\
let's check the members; |
The member needs a template. |
Howto compute the template ? |
let's compute the parameters. |
What is the first Parameter ? |
Its C. |
Howoto compute C -------/
|
March 13, 2017 Re: Recursive template instantiation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On 03/13/2017 03:26 PM, Jack Applegame wrote:
> I'm pretty sure that this code should compile
> (https://dpaste.dzfl.pl/cf1e1ee6ef4b):
>
> struct A(T) {
> ~this() {
> char[T.sizeof] data;
> }
> }
>
> struct B(T) {
> A!T foo;
> }
>
> struct C {
> B!C bar;
> }
>
> void main() {
> C c;
> }
>
> But it doesn't:
> /d300/f416.d(3): Error: struct f416.C no size because of forward
> reference /d300/f416.d(12): Error: template instance f416.B!(C) error
> instantiating
It compiles when it's a normal method instead of a destructor:
----
struct A(T) {
void m() {
char[T.sizeof] data;
}
}
/* ... rest as above ... */
----
I don't see how the destructor makes a difference. Soo, bug?
|
March 13, 2017 Re: Recursive template instantiation | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | On Monday, 13 March 2017 at 22:59:36 UTC, ag0aep6g wrote:
> On 03/13/2017 03:26 PM, Jack Applegame wrote:
>> I'm pretty sure that this code should compile
>> (https://dpaste.dzfl.pl/cf1e1ee6ef4b):
>>
>> struct A(T) {
>> ~this() {
>> char[T.sizeof] data;
>> }
>> }
>>
>> struct B(T) {
>> A!T foo;
>> }
>>
>> struct C {
>> B!C bar;
>> }
>>
>> void main() {
>> C c;
>> }
>>
>> But it doesn't:
>> /d300/f416.d(3): Error: struct f416.C no size because of forward
>> reference /d300/f416.d(12): Error: template instance f416.B!(C) error
>> instantiating
>
> It compiles when it's a normal method instead of a destructor:
>
> ----
> struct A(T) {
> void m() {
> char[T.sizeof] data;
> }
> }
> /* ... rest as above ... */
> ----
>
> I don't see how the destructor makes a difference. Soo, bug?
Try to use m.
|
March 14, 2017 Re: Recursive template instantiation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On 03/14/2017 12:02 AM, Stefan Koch wrote: > On Monday, 13 March 2017 at 22:59:36 UTC, ag0aep6g wrote: [...] >> ---- >> struct A(T) { >> void m() { >> char[T.sizeof] data; >> } >> } >> /* ... rest as above ... */ >> ---- >> >> I don't see how the destructor makes a difference. Soo, bug? > > Try to use m. Works no problem? ---- struct A(T) { void m() { char[T.sizeof] data; import std.stdio; writeln(T.sizeof); } } struct B(T) { A!T foo; } struct C { B!C bar; } void main() { C c; c.bar.foo.m(); } ---- Prints "1". |
March 14, 2017 Re: Recursive template instantiation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On 03/13/2017 11:58 PM, Stefan Koch wrote:
> On Monday, 13 March 2017 at 22:05:24 UTC, Jack Applegame wrote:
>> Is this a bug?
>
> No it's not
>
> struct C
> {
> B!C;
> }
> is an error.
>
> Howto compute C ? <------\
> let's check the members; |
> The member needs a template. |
> Howto compute the template ? |
> let's compute the parameters. |
> What is the first Parameter ? |
> Its C. |
> Howoto compute C -------/
I don't think that's it.
Here's a variant where B is not instantiated with C:
----
struct A()
{
~this() { enum s = C.sizeof; }
}
struct B() { A!() foo; }
struct C { B!() bar; }
----
How to compute C?
Check members.
For member `B!() bar;`, resolve `B!()`.
Check members of `B!()`.
For member `A!() foo;` resolve `A!()`.
Check members of `A!()`.
No members => size = 0 (or rather 1, I guess).
Bubble up.
But the compiler seems to get confused by the destructor. I guess it incorrectly(?) sees a need to analyze C again before it can finish up `A!()`?
|
Copyright © 1999-2021 by the D Language Foundation