Re: A couple of suggestions




Lauri Alanko <la@la.iki.fi> writes:

> I have a couple of suggestions for gtk and glib. All of these are trivial to
> implement, but I thought it best to ask for opinions before actually
> starting tweaking anything.
> 
> So:
> 
> A GAny type, which would be an union of all the primitive types in glib.
> This could be used as a "general" argument, where gpointer is used
> currently. (Such as in gtk callbacks, hashes etc..) The current practice,
> casting ints to gpointers and back, for instance, is not guaranteed to have
> any consistent behavior. Though it appears to work on most systems, it is
> still unreliable and ugly. Casting is a _conversion_ operation. Using an
> union is cleaner.

Although the C standard leaves casting between pointers and integers
undefined (except for saying that it is allowed), I'll stick to
my guns and say that storing small integers by casting into pointers
is safe on any platform that GTK is likely to run on.

Using unions would not only break every GTK program, it would break
them in a really obnoxious manner - because in 99.9 % of all
cases what is really being used is pointers - and casting from
Foo * to void * and back is 100% legitimate. (In fact, even without
the casts - in ANSI C)

  void
  callback (GtkWidget *widget, GtkWidget *some_other_widget)
  {
     ....
  }
  
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      callback, widget_x);

Is _not_ better written as:

  void
  callback (GtkWidget *widget, GAny any)
  {
     GtkWidget *widget = any.p;
  }

  GAny any;
  any.p = widget_x;
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      callback, any);

Or anything like that. If casting int <-> pointer offends you, don't
use it: use pointers to the real objects instead. If the use of such
casting in GTK bothers you - (it does me, but not enough to do
anything about it) - then patches to fix it would be accepted.

In might be nice to have macros that did the casting in a 
way that didn't produce warnings. For instance, on 32 bit
machines, and some 64 bit machines, the following

#define GUINT32_TO_POINTER(x) ((gpointer)(long)(x))
#define GPOINTER_TO_GUINT32(x) ((guint32)(long)(x))

(these need to be different on machines with 64 bit longs
and 32 bit pointers - I.e. SGI -n64)

But I think we should be very hesitant to force changes
all over GTK to accomodate the very rare cases where you
want to store ints as callback arguments or in GLists.
 
> For a real reinterpret cast (if such is really needed anywhere), the
> following might be sensible:
> 
> #define REINTERPRET_CAST(x, type) (*(type *)&(x))
> 
> (or use a shorter macro name..) This of course needs an lvalue.

Unfortunately, one doesn't always have lvalues, and actually,
your version looks somewhat _more_ dangerous to me. 

Casting directly just assumes that the compiler can convert
a pointer to an arithmetic type in some reasonable fashion.
Your version actually makes assumptions about memory layout.

(Imagine what happens on SGI -n64 when you try your REINTPRET_CAST
 from an pointer to an int)
 
> Then a real primitive hash would be useful, ie one which just stored objects
> in the hash without any mandated key/value pairing..

Could you eloborate? key/value pairing seems like a pretty
essential part of a hash to me... (Without that 

> And even the current hash should have a function to retrieve the key.
> Otherwise, what's the use of GCompareFunc, if you get into memory allocation
> problems if the key exists just in the hash and you can't free it..

g_hash_foreach will get you all the keys in the structure. I
can't see any meaningful way of looking up a single key in
a hash table. 

The normal case would be that your keys are being stored elsewhere as
well so they aren't "owned" by the hash table. What would be the point
of having a key/value pair in a hash table if you couldn't look
up the value because your key was _only_ in the hash table?

I suppose in both this and the above you are asking for a data
structure which is an unordered collection - a GBag, so to speak.
Not being a data structure wizard, I'm not quite sure what
advantages that would have over just using GSList.

> In gtk, it would be good to have a
> 
> typedef guint GtkSignalID;
> 
> Or something similar. This just to make code clearer to understand. IMO,
> unaliased ints should only be used for real numeric values. When ints are
> used for identifiers and the like, it should be apparent from the code.

Wouldn't hurt.
 
> In addition, converting to this will make it easier to some day change the
> type of the signal ids.

I can't really see that ever being necessary. (More than 2**32
types of signals?)
 
> And finally, you can define signals without having to add a vtable entry to
> the class object. That is good. It'd be nice to have a way to have virtual
> methods without the overhead of signals, as well.

That certainly is possible. Just put a function pointer in the
class structure and don't create a signal. (See the GtkRange
and GtkEditable classes for examples where this is done).
 
> All of these are easy to implement, and all of them just add functionality,
> they don't break anything. I'd be happy to do these. Are there any arguments
> against these?

Well, GAny would break just about everything... Other than that,
what you are saying sounds reasonable.

Regards,
                                        Owen



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