July 05, 2006
Peter C. Chapin wrote:
> Hello! I'm a C++ programmer who has started to look at D. I appreciate many of D's design decisions. However, I'm a little confused about how RAII is supported. It seems like it only semi-works. Consider the function below ('Example' is some class):
> 
> Example g()
> {
>   auto Example object1 = new Example;
>   auto Example object2 = new Example;
>   Example object3;
> 
>   if (f()) {
>     object3 = object1;
>   }
>   else {
>     object3 = object2;
>   }
>   return object3;
> }
> 
> The idea is that I want to return one of two local objects depending on what f() returns. Assume f() interacts with the user so its return value can't be known to the compiler. The object that is not returned must be cleaned up. Assume that it holds resources other than memory that need to be released.
> 
> In the example above it looks like both object1 and object2 are destroyed and thus the returned reference is invalid. However, if I remove 'auto' from the local declarations than object1 and object2 don't get destroyed until garbage collection time... which is too late. It looks like I'm left with explicitly deleting the object that I don't return, but this is manual resource management and not RAII.
> 
> To make this example more concrete, suppose the class in question represents an on-screen window. Function g() lets the user select one of two newly created windows, returning the window selected and removing the other from the screen.
> 
> Thanks in advance for any comments.

The reason the example "works" in C++ is not because RAII is any different in D - in D, as well as C++, both object1 and object2 get destroyed at the end of the return. What happens in C++ is the:
	object3 = object1;
makes a *copy* of object1 via the default (or explicit) copy constructor. In D, just a reference to object1's instance is copied.

You can make the D version behave like the C++ one as follows:

Example g()
{
  auto Example object1 = new Example;
  auto Example object2 = new Example;
  Example object3;

  if (f()) {
    object3 = new Example(object1);
  }
  else {
    object3 = new Example(object2);
  }
  return object3;
}

and then in the definition of Example, add the constructor:

	this(Example e)
	{
		...copy members...
	}

To explicitly run the destructor on an object, use:
	delete object1;
July 05, 2006
Walter Bright <newshound@digitalmars.com> wrote in news:e8f9b7$17u2$1@digitaldaemon.com:

> You can make the D version behave like the C++ one as follows:
> 
> Example g()
> {
>    auto Example object1 = new Example;
>    auto Example object2 = new Example;
>    Example object3;
> 
>    if (f()) {
>      object3 = new Example(object1);
>    }
>    else {
>      object3 = new Example(object2);
>    }
>    return object3;
> }

I see what you are saying. Thanks, that is helpful.

Peter
July 05, 2006
Derek Parnell wrote:
> On Wed, 05 Jul 2006 01:36:54 +0100, Bruno Medeiros wrote:
> 
>> Derek Parnell wrote:
>>
>> I'm not sure if you're just asking that without regards to the previous code, you're if asking that because you may have misunderstood the previous code.
> 
> Yep. I did misunderstand. My mistake, but I can see the 'trick' now. Is
> this method endorsed by Walter or is this just an artifact of the RAII
> implementation?
> 

Well, actually, now that I recall the spec, that behavior isn't valid: "Assignment to an auto, other than initialization, is not allowed."
But since the auto mechanism is under consideration to have some changes, the future behavior might be different and allow something like this. Or not at all.
For instance, if we have an auto that instead of being applied to variables, is applied to values, like this:
  auto Bar();
  Foo foo = auto Foo();
then how would one cancel the Foo() destruction? A new mechanism would be required, but then it might become a little awkward.

-- 
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
July 05, 2006
Derek Parnell wrote:
> On Wed, 05 Jul 2006 01:36:54 +0100, Bruno Medeiros wrote:
> 
>> Derek Parnell wrote:
>>
>> I'm not sure if you're just asking that without regards to the previous code, you're if asking that because you may have misunderstood the previous code.
> 
> Yep. I did misunderstand. My mistake, but I can see the 'trick' now. Is
> this method endorsed by Walter or is this just an artifact of the RAII
> implementation?

The latter I think.  Walter has said in the past that the compiler is free to allocate auto variables on the stack, it just isn't required.


Sean
July 06, 2006

Peter C. Chapin wrote:
<snip>
> In the example above it looks like both object1 and object2 are destroyed and thus the returned reference is invalid. However, if I remove 'auto' from the local declarations than object1 and object2 don't get destroyed until garbage collection time... which is too late. It looks like I'm left with explicitly deleting the object that I don't return, but this is manual resource management and not RAII.
> 
> Peter

I always had the impression that RAII indeed *is* manual resource management.
1 2
Next ›   Last »