Re: g_module_symbol signature



On Tue, 2004-03-02 at 17:55, Nicolas Peninguy wrote:
> Hello,
> 
> g_module_symbol last argument is of type gpointer *, i.e. something like
> void **, and this is used to represent a function pointer. I may be
> wrong, but I think (according to C99 standard) that a void pointer, and
> a function pointer are different.
> 
> This leads to the famous "dereferencing type-punned pointer will break
> strict-aliasing rules" warning when you use -fstrict-aliasing gcc option
> :
> 
> typedef void (* FunctionType)(void);
> FunctionType f;
> g_module_symbol (module, "function_name", (gpointer *)&f); // here
> 
> 
> (http://www.ethereal.com/lists/ethereal-dev/200309/msg00343.html has a
> good explanation of what this warning is about)
> 
> 
> I think "gpointer" would be a more correct type for the last argument
> (simply a pointer on a pointer of function). Another solution is to use
> a pointer on a void(void) function.
> 
> What do you think ? Should I file a bug ?

I don't think this has anything to do with function pointers:

          GtkWidget *child;

          gdk_window_get_user_data (window, (void **)&child);

Also produces the warning.

You are right that casting between function pointers and other pointers
is not guaranteed to work by the C spec, but it actually does work
on all platforms where GTK+ runs.

And changing the last argument of g_module_symbol to gpointer would
still run afoul of the C standard; using something like

 void (**symbol) (void)

as the last parameter would be more standards-compliant, but would
break existing applications that expect a gpointer * there.

In terms of the type punning warnings, they are actually basically
bogus warnings from GCC here; it's implausible that pointer returns
like this would run into problems with conceivable optimizations
that GCC might make.

Basically, what GCC is warning about is that in a function like:

 Gtkwidget *result;
 nullify (GtkWidget **a, void **b)
 {
   int result = *a;
   *b = NULL

   return result;
 }

The compiler is free to reorder the first two lines because *a and *b
can't point to the same memory location. So, if you called

 nullify (&widget, (void **)&widget);

you might get unexpected results. In the case where we 
we pass (void **)&widget as the first usage of the variable, there
aren't going to be any other live references to that memory.

We've worked around these warnings in Pango by using extra temporary
variables; we probably need to do the same in GTK+ for cleanliness...

Regards,
						Owen





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