January 12, 2008
Aarti_pl wrote:
> Frits van Bommel pisze:
>> Aarti_pl wrote:
>>> torhu pisze:
>>>> Aarti_pl wrote:
>> [How to heap-allocate a class reference?]
>>>
>>> I managed to overcome bug in DMD with below:
>>>
>>> void func(T)() {
>>>     static TYPE res;
>>>     res = new T;
>>>         return &res;
>>> }
>>>
>>> although it will cause memory leaks for every type for which the function is instantiated. So I consider bug in DMD as quite serious...
>>
>> That will only allocate one reference per type (*not* per call to the function). Try this workaround instead:
> 
> That's exactly what I said :-)

No, you say it will allocate a reference per instantiation and refer to this as a memory leak (presumably because they're not gc-ed after they're no longer in use).
My point was that a second call to the function (for the same type) will overwrite the location returned from the first call.
January 12, 2008
Frits van Bommel wrote:

>>>> although it will cause memory leaks for every type for which the function is instantiated. So I consider bug in DMD as quite serious...
>>>
>>> That will only allocate one reference per type (*not* per call to the function). Try this workaround instead:
>> 
>> That's exactly what I said :-)
> 
> No, you say it will allocate a reference per instantiation and refer to this as a memory leak (presumably because they're not gc-ed after they're no longer in use).

Yes, I probably should say "memory leak" (singular) to express what I meant.

> My point was that a second call to the function (for the same type) will overwrite the location returned from the first call.

That leads me to discuss another bug which I discovered.

Let's say we have program like below:
--------
import std.stdio;
struct Pattern(T : bool) {
    string beg = "test";
}

Pattern!(T) get(T)() {
    static Pattern!(T) pattern;
    return pattern;
}

void main() {
    writefln(get!(bool).beg);
    get!(bool).beg = "other";
    writefln(get!(bool).beg);
}
--------

Above program prints:
test
test

although I would expect it will print:
test
other

It seems that memory reserved for struct in template function is initialized every time the function is executed.

This behaviour is different when we change Pattern to be class instead of struct. Then it is possible to create kind of singleton pattern for every type.

What do you think?

BTW. Where should I discuss bugs? I have another dozen of them and would like to discuss some of them before posting to bugzilla. Is it better to post to d.learn or d.bugs?

-- 
Regards
Marcin Kuszczak (Aarti_pl)
-------------------------------------
Ask me why I believe in Jesus - http://www.zapytajmnie.com (en/pl)
Doost (port of few Boost libraries) - http://www.dsource.org/projects/doost/
-------------------------------------

January 13, 2008
Marcin Kuszczak wrote:
> That leads me to discuss another bug which I discovered. 
> 
> Let's say we have program like below:
> --------
> import std.stdio;
> struct Pattern(T : bool) {
>     string beg = "test";
> }
> 
> Pattern!(T) get(T)() {
>     static Pattern!(T) pattern;
>     return pattern;
> }
> 
> void main() {
>     writefln(get!(bool).beg);
>     get!(bool).beg = "other";
>     writefln(get!(bool).beg);
> }
> --------
> 
> Above program prints:
> test
> test
> 
> although I would expect it will print:
> test
> other
> 
> It seems that memory reserved for struct in template function is initialized
> every time the function is executed.

No, it's just initialized once. However, the struct itself isn't returned; a *copy* of it is returned. That copy is what's modified by the assignment. The second call will return a fresh copy of the original (with "test" remaining the string value).

> This behaviour is different when we change Pattern to be class instead of
> struct. Then it is possible to create kind of singleton pattern for every
> type.

Yes, class instances are passed by reference, so the assignment would change the 'static' instance (assuming you 'new' it the first time around, so there is one).
The same effect should be observed if you change the function to:
-----
Pattern!(T)* get(T)() {
    static Pattern!(T) pattern;
    return &pattern;
}
-----
for the struct version (returning a pointer to the global instance instead of a copy of it).

> What do you think?
> 
> BTW. Where should I discuss bugs? I have another dozen of them and would
> like to discuss some of them before posting to bugzilla. Is it better to
> post to d.learn or d.bugs?

If they are of the same kind as this one, you may want to stick to d.learn as it's not actually a bug :P.
(Or at least, it's a bug in your code rather than in the compiler; the compiler does exactly what I'd expect it to do and what IMO it should do)
January 13, 2008
Frits van Bommel wrote:

> No, it's just initialized once. However, the struct itself isn't returned; a *copy* of it is returned. That copy is what's modified by the assignment. The second call will return a fresh copy of the original (with "test" remaining the string value).
> 
>> This behaviour is different when we change Pattern to be class instead of struct. Then it is possible to create kind of singleton pattern for every type.
> 
> Yes, class instances are passed by reference, so the assignment would
> change the 'static' instance (assuming you 'new' it the first time
> around, so there is one).
> The same effect should be observed if you change the function to:
> -----
> Pattern!(T)* get(T)() {
>      static Pattern!(T) pattern;
>      return &pattern;
> }
> -----
> for the struct version (returning a pointer to the global instance
> instead of a copy of it).
> 

Thanks! Now this behaviour is clear for me.

>> 
>> BTW. Where should I discuss bugs? I have another dozen of them and would like to discuss some of them before posting to bugzilla. Is it better to post to d.learn or d.bugs?
> 
> If they are of the same kind as this one, you may want to stick to
> d.learn as it's not actually a bug :P.
> (Or at least, it's a bug in your code rather than in the compiler; the
> compiler does exactly what I'd expect it to do and what IMO it should do)

Some of them probably are bugs, and some of them are not. That's why I prefer to discuss them before posting to bugzilla.

-- 
Regards
Marcin Kuszczak (Aarti_pl)
-------------------------------------
Ask me why I believe in Jesus - http://www.zapytajmnie.com (en/pl)
Doost (port of few Boost libraries) - http://www.dsource.org/projects/doost/
-------------------------------------

January 14, 2008
Marcin Kuszczak wrote:
> Some of them probably are bugs, and some of them are not. That's why I
> prefer to discuss them before posting to bugzilla.

I'd say if you're not sure if they're bugs, best post here first. Then once you're sure something is a bug you can post it to bugzilla.
This way, D.bugs doesn't get cluttered with non-bugs.
1 2
Next ›   Last »