Re: Widget descriptors as unions



On 08/28/2015 09:09 PM, Jean-Marie Delapierre wrote:
Hi;

this mailing list is probably not the one you want to use —
development of the GLib/GTK+ libraries is discussed on
gtk-devel-list gnome org

On 14 May 2015 at 10:27, Jean-Marie Delapierre
<jean-marie delapierre 9online fr> wrote:

   I have coded in C language with GTK+ since a few months.
   In the first times, I have used the usual pointer casting provided
with the
   library: GTK_CONTAINER (my_window) for exemple.

   In my opinion, there are two disadvantages with this system:

   first, the widget pointers are not "object style" written,
   second, if you cast a pointer with a type which is not of one of its
parents
   widget, you get no error at compiling time and you get an execution
error
   only if you compile with widget type control.

   What I suggest is to define the widget descriptors as unions of pointers
   representing the hierarchy of the widgets.

No.

You misunderstand the way unions work in C. You're just adding a bunch
of identically pointer-sized fields inside the same union, which is
entirely pointless since you'll need to know the size of the
allocation of each one of them — thus, you'll need to define a
instance structure for each; it won't also do you any good: you're
exploiting the fact that GObject instance and class structures contain
their parent's instance and class structure, respectively, so
allocating a derived type will automatically allocate enough memory
for you to cast a pointer to its parent type.

Even if we used this trick (which is actually more verbose, more error
prone, and less clear than a cast all at the same time, in itself
quite a feat) you would just consume more space and have no benefit
over the existing 'include the parent structure inside the
instance/class structure of a derived type and cast'. It would also
not solve the issue of interfaces implemented by a type, since you can
add an interface to an existing type without breaking API/ABI, whereas
you cannot change the size of a structure or union compatibly — even
if you are, in effect, just allocating enough room for a single
pointer.

This would also not be API and ABI compatible, so it's an immediate
no-go.

   But, there is one disadvantage. This coding style is only available
in C and
   C++ languages.

Which is another moot point, since we use the type system for bindings
as well.

The GType type system is not without its flaws, but the fact that it's
a run-time type system is not really one of them. It's just the price
you pay for implementing additional types on top of the C type system.
Additionally, any language that allows casting is inherently hard (or,
in some cases, even impossible) to be fully validated at compile time.

Validation of the GType type system should be the realm of static code
analysis.

Ciao,
Emmanuele.

Hi,

I have let spend some time before to respond to your message, not to
react about your writing style.

Yes, I have made an enormous mistake. I have considered that the example
included in my original message would have been enough to make you
understand what I mean. Which was the mistake.

But, let me explain little more.

First of all, I do precisely NOTHING to the glib or GTK objects.

When you use the actual coding style with the GTK objects, you declare a
pointer which is usually of GtkWidget* type, and when you want to use it
in a function, you cast it like this: “gtk_window_set_title (GTK_WINDOW
(window)…” (in the preceding example, the keyword “window’ have been
declared as GtkWidget *window;).
In fact, doing this means that you use two different pointers (one of
GtkWidget* type and one of GtkWindow* type) sharing the same memory
location.

What I suggest is only and exactly the same, but with a coding style I
consider cleaner than the actual coding style and less error prone.

The trick is to declare a union of pointers (not objects), sharing the
same memory location, pointing to the types limited to only the valid
types for a given object.

What you have to notice is that in actual coding style, you declare a
descriptor which is a pointer to an object (with an indirection) and
with the coding style I suggest, you declare a descriptor which is of
union type (not a pointer). The indirection been carried by the
collection of pointers in the union.

Thus, the two coding styles a fully interoperable with one difference:
With the actual coding style, you can cast your pointer to a type which
is not compatible with the object you are pointing to. With the one I
suggest, you can’t. The compiler will detect the error for you before
the execution time.

In the end, you said that it’s more verbose. OK.

But, tell me which is more verbose:

This “gtk_window_set_title (GTK_WINDOW (window), "Hello World");”,
Or this “gtk_window_set_title (window.gtkwindow, "Hello World");”.

Regards.

Jean-Marie




_______________________________________________
gtk-list mailing list
gtk-list gnome org
https://mail.gnome.org/mailman/listinfo/gtk-list


You're still on the wrong list. Emmanuele is still right that the union
of child objects has to change when a parent type starts implementing an
interface. I also don't know how you would conveniently declare such a
union with mere macros.



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