Re: Type checking

On 03/17/2010 07:40 PM, Emmanuele Bassi wrote:
> a stop gap solution is to avoid doing crazy stuff
> like:
>   static void
>   my_blah_widget_init (MyBlahWidget *widget)
>   {
>     gtk_widget_set_foo (GTK_WIDGET (widget), TRUE);
>     gtk_widget_set_bar (GTK_WIDGET (widget), FALSE);
>     gtk_widget_set_baz (GTK_WIDGET (widget), 42);
>   }
> and do one since cast instead:
>   static void
>   my_blah_widget_init (MyBlahWidget *widget)
>   {
>     GtkWidget *w = GTK_WIDGET (widget);
>     gtk_widget_set_foo (w, TRUE);
>     gtk_widget_set_bar (w, FALSE);
>     gtk_widget_set_baz (w, 42);
>   } has a very small patch
that makes it so that:

    if (MY_IS_BLAH_WIDGET (widget)) {
        MyBlahWidget *mbw = MY_BLAH_WIDGET (widget);

only does a single type check (if you compile with optimization, and
my_blah_widget_get_type() is marked G_GNUC_CONST). I thought it would
fix your case too, but it doesn't, because theoretically
gtk_widget_set_foo() might cause @widget to stop being a widget, so it
needs to typecheck it again...

Pretty sure we could fix this too though, by changing _G_TYPE_CIT to use
"g_type_is_a (_inst->g_class->g_type, __t)" instead of
"g_type_check_instance_is_a (__inst, __t)". Except that instead of
g_type_is_a(), it would have to be a new method that does exactly the
same thing as g_type_is_a(), but is G_GNUC_PURE (and is therefore only
safe to call in cases where you know the type's hierarchy isn't going to
change in the future).

(Marking _get_type() methods G_GNUC_CONST makes it tricky to forcibly
initialize a type, but
has a patch to add "g_type_ensure()" to hide the complexity.)

Of course, this doesn't help Andrew's original case, where the is_a and
the cast are in separate functions...

-- Dan

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