From terop@students.cc.tut.fi Wed Aug  6 14:22:28 2003
Date: 12 Jul 1998 05:06:38 +0300
From: Tero Pulkkinen <terop@students.cc.tut.fi>
To: Christof Petig <christof.petig@wtal.de>
Cc: glaurent@worldnet.fr, gtkdev@gtk.org
Subject: Re: Strange bug within gtkmm (perhaps wrong memory region)


(this goes to gtkdev and the other people who know about the problem
already..)

I think I've found a bug in gtk's object initialization code. It only
appears when people derive from a gtk object and where this object's
object_init() calls (directly, or indirectly) virtual functions. Gtk
calls the most derived class methods with partly initialized object,
when (I think) it should be called only those methods that has been
initialized using their object_init method.

This is what happens:
  we have a widget FooDialog derived from GtkDialog

  we create an FooDialog object
  it calls object_init and class_init functions of all base classes first
  then calls gtk_dialog_init, which calls virtual functions.
  (basically gtk_container_add()). This virtual function should
  be calling gtk_dialog_add(), because only dialog part of it has been
  initialized with gtk_dialog_init().

  But it calls foodialog_add() method with uninitialized object and this
  fails. (well, it is unreasonable that all derived class virtual methods
  should handle situation where part of the object is not initialized
  properly..) (also, C++ handles it like that with constructors...  :)

Below is patch that fixes it. Maybe its time for gtk1.0.5.

(This fixes the dialog problems some people have been having with glade and
gtk--.)

-- 
-- Tero Pulkkinen -- terop@modeemi.cs.tut.fi --

--- gtktypeutils.cc.old Sun Jul 12 03:43:37 1998
+++ gtktypeutils.c      Sun Jul 12 03:47:43 1998
@@ -280,16 +280,17 @@

   klass = gtk_type_class (type);
   object = g_malloc0 (node->type_info.object_size);
-  object->klass = klass;

   for (i = node->n_supers; i > 0; i--)
     {
       GtkTypeNode *pnode;

       LOOKUP_TYPE_NODE (pnode, node->supers[i]);
+      object->klass = pnode->klass;
       if (pnode->type_info.object_init_func)
        (* pnode->type_info.object_init_func) (object);
     }
+  object->klass = klass;
   if (node->type_info.object_init_func)
     (* node->type_info.object_init_func) (object);