GNOME Bugzilla – Bug 529679
Non GObject classes and initializers
Last modified: 2008-07-22 01:10:26 UTC
public class Test { int x = 100; public int foo (int bar) { return x + bar; } } If you compile this then x wont ever be set to 100, and therefore will foo return the wrong results.
Confirming.
Created attachment 114176 [details] [review] add _instance_init function to compact class
Attached patch adds the _instance_init function to compact classes, and adds a call to it in each creation method immediately after the allocation call (g_slice_new0). Test case: [Compact] public class Foo { int x = 100; public Foo() { } public Foo.with_int(int i) { x = i; } public void foo () { stdout.printf("%d\n", x); } } void main(string[] args) { new Foo().foo(); new Foo.with_int(5).foo(); } Expected Results: 100 5 Relevant generated code: Foo* foo_new (void) { Foo* self; self = g_slice_new0 (Foo); foo_instance_init (self); return self; } Foo* foo_new_with_int (gint i) { Foo* self; self = g_slice_new0 (Foo); foo_instance_init (self); self->x = i; return self; } static void foo_instance_init (Foo * self) { self->x = 100; } It would be better if the _instance_init function and calls to it were not generated if there is nothing to initialize. But if so, then the function will be empty and gcc will optimise the call out anyway, so it's just an aesthetic issue.
I actually ask myself whether we want to support that at all for compact classes. Compact classes are technically really not any different from structs which are allocated on the heap. So they are really primitive constructs and may not provide an implicit constructor.
I don't see why not, since there is no overhead if there are no initialisers. Just consider it syntactic sugar for adding those initialisers to all of your construction methods. Anyway, construction of compact classes still doesn't deal with inheritance, so they are still quite primitive. :)
About comment #4: In that case should the int x = 100 have failed to compile. Telling me that I can't initialize a field of a primitive. This compiled just fine and in silence created unexpected behaviour. I think a language like vala wants to avoid especially this (since we're not making a new C++ here, I'll code in C++ if I want unexpected behaviour all the times)
Of course. Either we support this or there shall be an error if someone tries to initialize a compact class field that way. I thought this was implicitly clear ;).
After C++, I think it's good to always be explicit about things like this, though :) You see, with programming language developers, after C++, you never know. But you are right that I was pretty certain that your comment implied this.
I don't really see a reason not to support this. Patch looks good, please commit.
2008-07-22 Jared Moore <jaredm@svn.gnome.org> * gobject/valaccodeclassbinding.vala: * goblect/valaccodemethodbinding.vala: Generate *_instance_init function for compact classes to initialize fields, fixes bug 529679. * tests/classes-fields.vala: add test case Fixed in r1716.