digitalmars.D - no size yet for forward reference for nested structures
- qqiang (20/20) Jan 13 2015 The following code:
- bearophile (6/8) Jan 14 2015 Your code gives me a different error (Error: PowerHeap!int is
- qqiang (27/35) Jan 14 2015 Thanks for your reply.
- ketmar via Digitalmars-d (8/33) Jan 14 2015 there is a circular dependency in your data structures. you're defining
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (15/48) Jan 14 2015 Reduced:
- ketmar via Digitalmars-d (3/22) Jan 14 2015 i don't know: i've never used `std.container` anyway. ;-)
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (6/28) Jan 14 2015 It looks like this came up not too long ago:
- Steven Schveighoffer (48/100) Jan 15 2015 In my not-so-expert opinion, I think this is somewhat of a bug, but not
- zeljkog (6/6) Jan 15 2015 This compiles:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (14/20) Jan 15 2015 So does using an 'interface', which may be more desirable in some cases:
- Steven Schveighoffer (4/10) Jan 15 2015 Then use DList?
- zeljkog (3/16) Jan 15 2015 SList.Range has moveFront, DList.Range does not.
- zeljkog (3/22) Jan 15 2015 And yes, looks like hasAliasing!Node (from std.algorithm.move) is only
- Steven Schveighoffer (5/29) Jan 16 2015 I think this is likely the issue. std.algorithm.move should not have to
- Steven Schveighoffer (4/5) Jan 16 2015 https://issues.dlang.org/show_bug.cgi?id=13990
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (35/55) Jan 14 2015 First a reminder that this sort of question is more suitable to the
- qqiang (27/89) Jan 14 2015 Thanks for your reminder.
The following code: ```D template PowerHeap(T) { import std.container : SList; private alias PowerForest = SList!PowerNode; private final class PowerNode { ... } final class PowerHead { ... } } unittest { PowerHeap!int h; } ``` failed to compile and get the error: PowerHeap!int.PowerNode: no size yet for forward reference. I've googled and found no straightforward solution to this issue. The how can I modify my code to eliminate this error?
Jan 13 2015
qqiang:I've googled and found no straightforward solution to this issue. The how can I modify my code to eliminate this error?Your code gives me a different error (Error: PowerHeap!int is used as a type). What if you replace the SList with a dynamic array? Bye, bearophile
Jan 14 2015
On Wednesday, 14 January 2015 at 08:31:08 UTC, bearophile wrote:qqiang:Thanks for your reply. I'm sorry that I've provided wrong code. This is the exact code: ------------------------------------------------------------------- template PowerHeap(T) { import std.container : SList; private alias PowerForest = SList!PowerNode; private final class PowerNode { private { T payload_; uint rank_; PowerForest children_; } } final class PowerHeap { private { PowerNode top_; PowerForest forest_; uint size_; } } } unittest { PowerHeap!int h; } ---------------------------------------------------------------------- My compiler is v2.066.1I've googled and found no straightforward solution to this issue. The how can I modify my code to eliminate this error?Your code gives me a different error (Error: PowerHeap!int is used as a type). What if you replace the SList with a dynamic array? Bye, bearophile
Jan 14 2015
On Wed, 14 Jan 2015 10:41:07 +0000 qqiang via Digitalmars-d <digitalmars-d puremagic.com> wrote:template PowerHeap(T) { import std.container : SList; =20 private alias PowerForest =3D SList!PowerNode; =20 private final class PowerNode { private { T payload_; uint rank_; PowerForest children_; } } =20 final class PowerHeap { private { PowerNode top_; PowerForest forest_; uint size_; } } } =20 unittest { PowerHeap!int h; }there is a circular dependency in your data structures. you're defining `PowerNode` in the terms of... `PowerNode`. this won't work. your `PowerForest` definition depends of complete `PowerNode` definition, but `PowerNode` definition depends of complete `PowerForest` definition. don't do that.
Jan 14 2015
On 01/14/2015 02:53 AM, ketmar via Digitalmars-d wrote:On Wed, 14 Jan 2015 10:41:07 +0000 qqiang via Digitalmars-d <digitalmars-d puremagic.com> wrote:Reduced: import std.container; class Node { SList!Node children; } void main() {} Error: class deneme.Node no size yet for forward reference I wonder why an SList of a reference type requires the size of the elements? The following compiles but is that a pointer to a class variable or a class object? How can we even use the 'children' member? SList!(Node*) children; Alitemplate PowerHeap(T) { import std.container : SList; private alias PowerForest = SList!PowerNode; private final class PowerNode { private { T payload_; uint rank_; PowerForest children_; } } final class PowerHeap { private { PowerNode top_; PowerForest forest_; uint size_; } } } unittest { PowerHeap!int h; }there is a circular dependency in your data structures. you're defining `PowerNode` in the terms of... `PowerNode`. this won't work. your `PowerForest` definition depends of complete `PowerNode` definition, but `PowerNode` definition depends of complete `PowerForest` definition. don't do that.
Jan 14 2015
On Wed, 14 Jan 2015 07:09:44 -0800 Ali =C3=87ehreli via Digitalmars-d <digitalmars-d puremagic.com> wrote:Reduced: =20 import std.container; =20 class Node { SList!Node children; } =20 void main() {} =20 Error: class deneme.Node no size yet for forward reference =20 I wonder why an SList of a reference type requires the size of the=20 elements? The following compiles but is that a pointer to a class=20 variable or a class object? How can we even use the 'children' member? =20 SList!(Node*) children;i don't know: i've never used `std.container` anyway. ;-)
Jan 14 2015
On 01/14/2015 07:39 AM, ketmar via Digitalmars-d wrote:On Wed, 14 Jan 2015 07:09:44 -0800 Ali Çehreli via Digitalmars-d <digitalmars-d puremagic.com> wrote:It looks like this came up not too long ago: http://forum.dlang.org/thread/akkrerlsjutdfmzswsbo forum.dlang.org#post-akkrerlsjutdfmzswsbo:40forum.dlang.org I think this is a bug but I will wait for others to confirm. AliReduced: import std.container; class Node { SList!Node children; } void main() {} Error: class deneme.Node no size yet for forward reference I wonder why an SList of a reference type requires the size of the elements? The following compiles but is that a pointer to a class variable or a class object? How can we even use the 'children' member? SList!(Node*) children;i don't know: i've never used `std.container` anyway. ;-)
Jan 14 2015
On 1/14/15 10:09 AM, Ali Çehreli wrote:On 01/14/2015 02:53 AM, ketmar via Digitalmars-d wrote: > On Wed, 14 Jan 2015 10:41:07 +0000 > qqiang via Digitalmars-d <digitalmars-d puremagic.com> wrote: > >> template PowerHeap(T) { >> import std.container : SList; >> >> private alias PowerForest = SList!PowerNode; >> >> private final class PowerNode { >> private { >> T payload_; >> uint rank_; >> PowerForest children_; >> } >> } >> >> final class PowerHeap { >> private { >> PowerNode top_; >> PowerForest forest_; >> uint size_; >> } >> } >> } >> >> unittest { >> PowerHeap!int h; >> } > there is a circular dependency in your data structures. you're defining > `PowerNode` in the terms of... `PowerNode`. this won't work. > > your `PowerForest` definition depends of complete `PowerNode` > definition, but `PowerNode` definition depends of complete > `PowerForest` definition. > > don't do that. > Reduced: import std.container; class Node { SList!Node children; } void main() {} Error: class deneme.Node no size yet for forward reference I wonder why an SList of a reference type requires the size of the elements? The following compiles but is that a pointer to a class variable or a class object? How can we even use the 'children' member? SList!(Node*) children; AliIn my not-so-expert opinion, I think this is somewhat of a bug, but not in the compiler. Note that it depends heavily on the definition of SList. If SList starts using pieces of S, it may confuse or create issues with the compiler. A simple test is to declare an opaque class: class S; void main() { S foo; } This works (at least it works to compile, not to link as the linker can't find the class symbol) Now, if I do this: import std.container; class S; alias listofs = SList!S; void main() { S foo; } I get the following audit from the compiler: /usr/share/dmd/src/phobos/std/traits.d(2032): Error: class testforward.S unknown size /usr/share/dmd/src/phobos/std/traits.d(2198): Error: template instance std.traits.FieldTypeTuple!(S) error instantiating /usr/share/dmd/src/phobos/std/traits.d(2349): instantiated from here: RepresentationTypeTuple!(S) /usr/share/dmd/src/phobos/std/traits.d(2692): instantiated from here: hasRawAliasing!(S) /usr/share/dmd/src/phobos/std/algorithm.d(1888): instantiated from here: hasAliasing!(S) /usr/share/dmd/src/phobos/std/container.d(1008): Error: template instance std.algorithm.move!(S) error instantiating testforward.d(4): instantiated from here: SList!(S) /usr/share/dmd/src/phobos/std/range.d(3149): Error: template instance std.range.hasAssignableElements!(Range) error instantiating /usr/share/dmd/src/phobos/std/container.d(1359): Error: template instance std.range.Take!(Range) error instantiating testforward.d(4): instantiated from here: SList!(S) So I think it's SList's invocation of move, which in turn checks hasAliasing, which in turn needs S's total definition (as it starts getting the fields of S). I think hasAliasing!(someclass) needs to be short circuited to true, or slist needs to use some other mechanism. I don't know how SList works exactly, maybe it does not actually allocate a list of class references, but instead emplaces them. In that case, you may be out of luck. -Steve
Jan 15 2015
This compiles: import std.container; class Node { DList!Node children; }
Jan 15 2015
On 01/15/2015 06:56 AM, zeljkog wrote:This compiles: import std.container; class Node { DList!Node children; }So does using an 'interface', which may be more desirable in some cases: import std.container; interface Iface {} class Node : Iface { SList!Iface children; } void main() { auto n = new Node(); } Ali
Jan 15 2015
On 1/15/15 9:56 AM, zeljkog wrote:This compiles: import std.container; class Node { DList!Node children; }Then use DList? DList is not SList, they were written by different people. -Steve
Jan 15 2015
On 15.01.15 23:30, Steven Schveighoffer wrote:On 1/15/15 9:56 AM, zeljkog wrote:SList.Range has moveFront, DList.Range does not. If I comment out SList.Range.moveFront, it compiles with SList.This compiles: import std.container; class Node { DList!Node children; }Then use DList? DList is not SList, they were written by different people. -Steve
Jan 15 2015
On 16.01.15 08:04, zeljkog wrote:On 15.01.15 23:30, Steven Schveighoffer wrote:And yes, looks like hasAliasing!Node (from std.algorithm.move) is only problem.On 1/15/15 9:56 AM, zeljkog wrote:SList.Range has moveFront, DList.Range does not. If I comment out SList.Range.moveFront, it compiles with SList.This compiles: import std.container; class Node { DList!Node children; }Then use DList? DList is not SList, they were written by different people. -Steve
Jan 15 2015
On 1/16/15 2:18 AM, zeljkog wrote:On 16.01.15 08:04, zeljkog wrote:I think this is likely the issue. std.algorithm.move should not have to care what is inside a class to move a reference to it. I will file a bug. Thanks for digging into this. -SteveOn 15.01.15 23:30, Steven Schveighoffer wrote:And yes, looks like hasAliasing!Node (from std.algorithm.move) is only problem.On 1/15/15 9:56 AM, zeljkog wrote:SList.Range has moveFront, DList.Range does not. If I comment out SList.Range.moveFront, it compiles with SList.This compiles: import std.container; class Node { DList!Node children; }Then use DList? DList is not SList, they were written by different people. -Steve
Jan 16 2015
On 1/16/15 1:24 PM, Steven Schveighoffer wrote:I will file a bug. Thanks for digging into this.https://issues.dlang.org/show_bug.cgi?id=13990 https://github.com/D-Programming-Language/phobos/pull/2876 -Steve
Jan 16 2015
First a reminder that this sort of question is more suitable to the D.learn newsgroup. On 01/13/2015 10:41 PM, qqiang wrote:The following code: ```D template PowerHeap(T) { import std.container : SList; private alias PowerForest = SList!PowerNode; private final class PowerNode { ... } final class PowerHead { ... } } unittest { PowerHeap!int h; } ```I started with your code and produced the following one: template PowerHeap(T) { import std.container : SList; private alias PowerForest = SList!PowerNode; private final class PowerNode { // ... } final class PowerHead { // ... } } unittest { PowerHeap!int h; // <-- Compilation error here } void main() {}failed to compile and get the error: PowerHeap!int.PowerNode: no size yet for forward reference.What compiler and version are you using? I received a different error with the git head dmd: Error: PowerHeap!int is used as a type The compiler is right, PowerHeap!int is a template instantiation that wraps a number of definitions. Did you mean one of those? The following compiles: unittest { PowerHeap!int.PowerHead h; // <-- now compiles }I've googled and found no straightforward solution to this issue. The how can I modify my code to eliminate this error?Please provide exact code so that... Oh, wait! I've just noticed that your error message has PowerHeap!int.PowerNode in it. Let me try with that: unittest { PowerHeap!int.PowerNode h; // <-- this compiles as well } Yeah, please provide exact code. :) Ali
Jan 14 2015
On Wednesday, 14 January 2015 at 08:31:13 UTC, Ali Çehreli wrote:First a reminder that this sort of question is more suitable to the D.learn newsgroup. On 01/13/2015 10:41 PM, qqiang wrote:Thanks for your reminder. I'm sorry that I've provided wrong code. This is the exact code: ------------------------------------------------------------------- template PowerHeap(T) { import std.container : SList; private alias PowerForest = SList!PowerNode; private final class PowerNode { private { T payload_; uint rank_; PowerForest children_; } } final class PowerHeap { private { PowerNode top_; PowerForest forest_; uint size_; } } } unittest { PowerHeap!int h; } ---------------------------------------------------------------------- My compiler is v2.066.1The following code: ```D template PowerHeap(T) { import std.container : SList; private alias PowerForest = SList!PowerNode; private final class PowerNode { ... } final class PowerHead { ... } } unittest { PowerHeap!int h; } ```I started with your code and produced the following one: template PowerHeap(T) { import std.container : SList; private alias PowerForest = SList!PowerNode; private final class PowerNode { // ... } final class PowerHead { // ... } } unittest { PowerHeap!int h; // <-- Compilation error here } void main() {}failed to compile and get the error: PowerHeap!int.PowerNode:no sizeyet for forward reference.What compiler and version are you using? I received a different error with the git head dmd: Error: PowerHeap!int is used as a type The compiler is right, PowerHeap!int is a template instantiation that wraps a number of definitions. Did you mean one of those? The following compiles: unittest { PowerHeap!int.PowerHead h; // <-- now compiles }I've googled and found no straightforward solution to thisissue. Thehow can I modify my code to eliminate this error?Please provide exact code so that... Oh, wait! I've just noticed that your error message has PowerHeap!int.PowerNode in it. Let me try with that: unittest { PowerHeap!int.PowerNode h; // <-- this compiles as well } Yeah, please provide exact code. :) Ali
Jan 14 2015