digitalmars.D.learn - Forward references and more
- bearophile (40/40) Oct 12 2009 What's wrong with this code?
- bearophile (1/2) Oct 12 2009 Ignore this line, please :-)
- Steven Schveighoffer (15/55) Oct 12 2009 It looks strange what you are doing. A Foo can have a memory pool of a ...
- bearophile (6/18) Oct 12 2009 It works if I use a global variable. But I'd like to not used global var...
- Steven Schveighoffer (18/38) Oct 12 2009 A static variable is essentially a scoped global variable. I think it
- bearophile (15/21) Oct 13 2009 It doesn't compile with static variables too, you just need few seconds ...
- Steven Schveighoffer (13/37) Oct 13 2009 If that fails, then it seems like a bug to me.
- Ary Borenszweig (13/30) Oct 12 2009 The compiler does this:
- bearophile (8/14) Oct 12 2009 I don't know. I don't know enough about compilers.
What's wrong with this code? struct MemoryPool(T) { alias T[100_000 / T.sizeof] Chunk; Chunk*[] chunks; } struct Foo { int x; MemoryPool!(Foo) pool; } void main() {} It prints "Error: struct problem.Foo no size yet for forward reference". T.sizeof must be 8 in all cases. So I have tried to pull pool out: struct MemoryPool(T) { alias T[100_000 / T.sizeof] Chunk; Chunk*[] chunks; } MemoryPool!(Foo) pool; struct Foo { int x; // here uses pool } void main() {} But there's a problem still: Error: struct problem2.Foo no size yet for forward reference To compile the code I have to move pool forward still: struct MemoryPool(T) { alias T[100_000 / T.sizeof] Chunk; Chunk*[] chunks; } struct Foo { int x; // here uses pool } MemoryPool!(Foo) pool; void main() {} When possible it's better to avoid global variables. To avoid the global variable I may pass the instance pool to Foo. But to do this Foo has to become a struct template. But I am not sure how I can do this. Do you have any comments or suggestions? Bye and thank you, bearophile
Oct 12 2009
T.sizeof must be 8 in all cases.Ignore this line, please :-)
Oct 12 2009
On Mon, 12 Oct 2009 05:26:58 -0400, bearophile <bearophileHUGS lycos.com> wrote:What's wrong with this code? struct MemoryPool(T) { alias T[100_000 / T.sizeof] Chunk; Chunk*[] chunks; } struct Foo { int x; MemoryPool!(Foo) pool; } void main() {} It prints "Error: struct problem.Foo no size yet for forward reference". T.sizeof must be 8 in all cases. So I have tried to pull pool out: struct MemoryPool(T) { alias T[100_000 / T.sizeof] Chunk; Chunk*[] chunks; } MemoryPool!(Foo) pool; struct Foo { int x; // here uses pool } void main() {} But there's a problem still: Error: struct problem2.Foo no size yet for forward reference To compile the code I have to move pool forward still: struct MemoryPool(T) { alias T[100_000 / T.sizeof] Chunk; Chunk*[] chunks; } struct Foo { int x; // here uses pool } MemoryPool!(Foo) pool; void main() {} When possible it's better to avoid global variables. To avoid the global variable I may pass the instance pool to Foo. But to do this Foo has to become a struct template. But I am not sure how I can do this. Do you have any comments or suggestions?It looks strange what you are doing. A Foo can have a memory pool of a lot of Foo's? Do you mean to make the memory pool static? I think that might work. I think the main problem is you are defining MemoryPool!(Foo).Chunk which specifically needs to know the size of Foo before Foo is completely declared. It's like you are doing this: struct X { X x; } Which clearly is incorrect. -Steve
Oct 12 2009
Steven Schveighoffer:It looks strange what you are doing. A Foo can have a memory pool of a lot of Foo's? Do you mean to make the memory pool static?Right and yes.I think that might work.<It works if I use a global variable. But I'd like to not used global variables when possible.I think the main problem is you are defining MemoryPool!(Foo).Chunk which specifically needs to know the size of Foo before Foo is completely declared. It's like you are doing this: struct X { X x; } Which clearly is incorrect.But MemoryPool.sizeof is always 8 (on a 32 bit system) because an alias takes no space. So T.sizeof must be 12. I'd like the compiler to understand this. Bye and thank you, bearophile
Oct 12 2009
On Mon, 12 Oct 2009 15:38:07 -0400, bearophile <bearophileHUGS lycos.com> wrote:Steven Schveighoffer:A static variable is essentially a scoped global variable. I think it will work if you make it static. I've used plenty of static variables that are instances of the struct they are declared in.It looks strange what you are doing. A Foo can have a memory pool of a lot of Foo's? Do you mean to make the memory pool static?Right and yes.I think that might work.<It works if I use a global variable. But I'd like to not used global variables when possible.But you are also declaring the type of the chunk. I don't think it would complain if you were not trying to define a type that required the size of Foo. For example, if you did something like: struct MemoryPool(T) { T[] chunks; } I think it would work, because you aren't trying to define a type which *requires* the size of T before T is fully declared. It's sort of a chicken and egg thing. But since I think you are implementing the memory pool incorrectly (it makes no sense for each instance of an item to have a pool of itself), you should reexamine what you are trying to do. -SteveI think the main problem is you are defining MemoryPool!(Foo).Chunk which specifically needs to know the size of Foo before Foo is completely declared. It's like you are doing this: struct X { X x; } Which clearly is incorrect.But MemoryPool.sizeof is always 8 (on a 32 bit system) because an alias takes no space. So T.sizeof must be 12. I'd like the compiler to understand this.
Oct 12 2009
Steven Schveighoffer:A static variable is essentially a scoped global variable. I think it will work if you make it static. I've used plenty of static variables that are instances of the struct they are declared in.It doesn't compile with static variables too, you just need few seconds to try it on Codepad: http://codepad.org/QHm2QNQ7 struct MemoryPool(T) { alias T[100_000 / T.sizeof] Chunk; static Chunk*[] chunks; } struct Foo { int x; static MemoryPool!(Foo) pool; } void main() {}But since I think you are implementing the memory pool incorrectly (it makes no sense for each instance of an item to have a pool of itself), you should reexamine what you are trying to do.Next time I show code I'll replace all variable and type names with foo, baz, spam, etc. The memory pool in my dlibs is implemented correctly (I think). The code I've shown is just a reduced case, where I have removed the "static" too :-) Bye, bearophile
Oct 13 2009
On Tue, 13 Oct 2009 07:30:11 -0400, bearophile <bearophileHUGS lycos.com> wrote:Steven Schveighoffer:If that fails, then it seems like a bug to me. This works: struct Foo { static Foo var; int x; } which seems to suggest that static variables are treated like globals. You should submit a bug to get that fixed.A static variable is essentially a scoped global variable. I think it will work if you make it static. I've used plenty of static variables that are instances of the struct they are declared in.It doesn't compile with static variables too, you just need few seconds to try it on Codepad: http://codepad.org/QHm2QNQ7 struct MemoryPool(T) { alias T[100_000 / T.sizeof] Chunk; static Chunk*[] chunks; } struct Foo { int x; static MemoryPool!(Foo) pool; } void main() {}It makes no sense to have a memory pool *per* instance, it makes more sense to have one pool for many instances (whether it's static or not). -SteveBut since I think you are implementing the memory pool incorrectly (it makes no sense for each instance of an item to have a pool of itself), you should reexamine what you are trying to do.Next time I show code I'll replace all variable and type names with foo, baz, spam, etc. The memory pool in my dlibs is implemented correctly (I think). The code I've shown is just a reduced case, where I have removed the "static" too :-)
Oct 13 2009
Steven Schveighoffer wrote:On Mon, 12 Oct 2009 05:26:58 -0400, bearophile <bearophileHUGS lycos.com> wrote:The compiler does this: Instantiate MemoryPool!(Foo) But for that it needs to know Foo.sizeof. But for that it needs to know MemoryPool!(Foo).sizeof. But for that it needs to instantiate MemoryPool!(Foo) and find it's size. etc. I can see MemoryPool!(Foo) sizeof doesn't depend at all of T.sizeof because it just has a pointer. But how do you suggest to fix the compiler to understand that? What I can see is that to know MemoryPool!(Foo).sizeof the type of the alias doesn't need to be solved completely... but what would you recommend the compiler to do?What's wrong with this code? struct MemoryPool(T) { alias T[100_000 / T.sizeof] Chunk; Chunk*[] chunks; } struct Foo { int x; MemoryPool!(Foo) pool; } void main() {} It prints "Error: struct problem.Foo no size yet for forward reference". T.sizeof must be 8 in all cases.
Oct 12 2009
Ary Borenszweig:I can see MemoryPool!(Foo) sizeof doesn't depend at all of T.sizeof because it just has a pointer.Well, a dynamic array of pointers, but the situation is the same.But how do you suggest to fix the compiler to understand that?<I don't know. I don't know enough about compilers.What I can see is that to know MemoryPool!(Foo).sizeof the type of the alias doesn't need to be solved completely... but what would you recommend the compiler to do?To see what I can see. And terminate this little dance. If that's not possible, then I'd like to have a syntax to give the necessary hint to the (less than smart) compiler. For example saying the size of one or both structs. This was just an example, but it's not the first time I fall in this problem when I create data structures in D. Bye and thank you, bearophile
Oct 12 2009