Re: [Vala] Ownership and strings



On Mon, 2009-06-01 at 04:04 +0200, Jiří Zárevúcky wrote:
Dne 1. červen 2009 0:51 Yu Feng <rainwoodman gmail com> napsal(a):
What aspects about string handling do you want to know though?

For the memory management maybe you want to search for the keyword
`Compact' in the tutorial about the references and ownership aspect of
string and other compact types in vala.

http://live.gnome.org/Vala/Tutorial


Oh... for some reason I forgot to read that tutorial :-/ Final exams
are obviously frying my brain...

I wrote that paragraph and would like to learn some feedback from you if
it is clear or ambiguous.


Quite clear, I understand the concept now. Thanks. :)

Thanks too!

Although there is a case I'm not really sure about...

class StringTest
{
      public string some_string
      {
              get {
                      var s = "fdfdf";
You can't create a initially unowned memory object. 
 
The string constants, like "fdfdf" are statically owned. In other words,
the owner is the program's global heap. As long as the program is in the
memory, they are not destroyed. The semantic analyzer deducts that `var
s' should be a strong reference. Now because string is a compact class,
"fdfdf" is copied with g_strcpy(as specified in glib-2.0.vapi:803) to
associate `var s' with a new object.

You are right member properties, aka member fields with getter and
setters are special. Although they are not declared as weak/unowned, the
reference you get by the implicit invocation of the getter is always
unowned. The reason for this default behavior is to be consistent with
older version and GTK conventions. This(important fact) is not mentioned
anywhere other than the mail-list or the bugzilla, as far as I know.

Now you want to return this strong reference within a method that
returns a weak reference. Because after the function has returned, the
local variable `var s' is out of scope, and the object `var s' pointing
to is destroyed. However the returned weak reference of this destroyed
object is passed out. The innocent caller of this method now receives an
invalid weak reference pointing to an ruined memory area. This is an
undefined behavior; vala compiler avoids this wrong thing at the
compilation stage.

For your example, these three alternatives should work:
class StringTest
{
        public string some_string
        {
                get {
   /* A weak reference to a statically owned string */
                        return "fdfdf";
                }
        }
}

or 

class StringTest 
{
        private string _some_string;
        public string some_string
        {
                get {
                        /* plenty of them in vala*/
                        if(_some_string == null) {
                                _some_string = "dfdfd";
                        }
                        return _some_string;
                }
        }
}

or, a worst one:

class StringTest 
{
        public string # some_string
        {
                get {
/* Declare the method as returning an owned(strong) reference to a string */
                        var s = "fdfdf";
                        return s
                }
        }
}

I hope this explanation clarifies it all.

- Yu
                      return s;
              }
      }
}


Now when I try to compile it, it gives me an error.
"Local variable with strong reference used as return value and method
return type has not been declared to transfer ownership".

Now it's fairly obvious this is some special property behavior (normal
method works fine), but I don't really understand why does it differ.

On the other hand, it works when I change the variable to "unowned
string". Then it compiles, but the string isn't owned by anything. Is
it even allocated? If so, I guess the ownership is transferred to the
first strong variable it is assigned to, right? Then, what happens
when the variable goes out of scope without any strong assignment?

I would really appreciate a paragraph about how initially unowned
non-reference-counted objects are handled. :) Thanks in advance.

BTW: there is no such initially unowned object in native VALA, no matter
it is compact or reference counted. I bet you heard about the name from
GObject/GTK. Refer to gobject-2.0.vapi:222. If an GLib object is an
instance of InitiallyUnowned, vala will sink it for you, then pass the
ownership to the first reference variable.






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]