Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
October 12, 2009 Forward references and more | ||||
---|---|---|---|---|
| ||||
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 |
October 12, 2009 Re: Forward references and more | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > T.sizeof must be 8 in all cases.
Ignore this line, please :-)
|
October 12, 2009 Re: Forward references and more | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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
|
October 12, 2009 Re: Forward references and more | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 |
October 12, 2009 Re: Forward references and more | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer wrote:
> 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.
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?
|
October 13, 2009 Re: Forward references and more | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ary Borenszweig | 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 |
October 13, 2009 Re: Forward references and more | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Mon, 12 Oct 2009 15:38:07 -0400, bearophile <bearophileHUGS@lycos.com> wrote: > 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. 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. > > >> 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. 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. -Steve |
October 13, 2009 Re: Forward references and more | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 |
October 13, 2009 Re: Forward references and more | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Tue, 13 Oct 2009 07:30:11 -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 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() {} 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. >> 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 :-) 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). -Steve |
Copyright © 1999-2021 by the D Language Foundation