GNOME Bugzilla – Bug 389585
G_DEFINE_TYPE hack for header files
Last modified: 2017-10-11 09:13:58 UTC
it would be neat to have header files like this: #ifndef _desrt_mapper_world_h_ #define _desrt_mapper_world_h_ #include <gtk/gtk.h> #define DESRT_MAPPER_TYPE_WORLD \ desrt_mapper_world_get_type () G_DEFINE_HEADER (DESRT_MAPPER, WORLD, desrt_mapper_world, DesrtMapperWorld) struct _DesrtMapperWorld { GtkDrawingArea parent; int zoom; }; struct _DesrtMapperWorldClass { GtkDrawingAreaClass parent_class; }; GtkWidget *desrt_mapper_world_new (int zoom); #endif
Created attachment 78887 [details] [review] an idea for how we could do glib boilerplate for headers... i'm still not sure what the best way to handle the G_TYPE_OBJECT macro is..... i'm not sure there is a good way. in any case, this still saves a lot of typing.
one thing i should mention... according to this document, C99 assigns the same meaning to "static inline" as does GNU C: http://www.greenend.org.uk/rjk/2003/03/inline.html
If "save typing" is the motivation here, why not write a macro/template for your favourite editor instead ?
same reason we have G_DEFINE_TYPE.
agreed, but G_DEFINE_TYPE does not introduce inline functions. I don't really like that, mostly due to the extern inline/static inline mess. gcc just recently changed again in this area.
two things worth noting: 1) glib already makes use of static inlines (for example: g_string_append_c() in gstring.h). 2) for some reason, there is a G_CAN_INLINE macro that seems to exist explicitly for this purpose (even though if your C compiler -doesn't- support this then it is broken by definition).
behdad just suggested that this might better be called G_DECLARE_TYPE. i agree. the name i chose was pretty random -- i didn't put any thought into it.
(In reply to comment #0) > it would be neat to have header files like this: > #define DESRT_MAPPER_TYPE_WORLD \ > desrt_mapper_world_get_type () > G_DEFINE_HEADER (DESRT_MAPPER, WORLD, > desrt_mapper_world, > DesrtMapperWorld) note that you miss a semicolon at the end of this statement which screwes autoindenting editors and indent. in any case, i consider this too much magic, it's allmost striving towards a second preprocessing stage ala bug 363231. apart from that, there are real implementation problems with what you suggest, whicih is the main reason GObject didn't provide anything like this from the start: - glib/gtk+ cannot make use of C99 features, here's the last evaluation from 2006: http://mail.gnome.org/archives/gtk-devel-list/2006-January/msg00057.html - we can't depend on inline functions to work with every compiler, that's why we have G_CAN_INLINE+friends and implement special handling in glib to always provide a compiled version for all inline functions on systems without inlining support. for the moment (say until we have e.g. an IDL compiler for glib/gobject/dbus), the best advice is that of Matthias (comment #3): > If "save typing" is the motivation here, why not write a macro/template for > your favourite editor instead ?
Created attachment 101982 [details] glib-gentype What(In reply to comment #8) > for the moment (say until we have e.g. an IDL compiler for glib/gobject/dbus), > the best advice is that of Matthias (comment #3): > > If "save typing" is the motivation here, why not write a macro/template for > > your favourite editor instead ? > Agreed. So why not ship some templates and/or a tool in the sprit of glib-genmarshal or glib-mkenums? Guess every serious GObject hacker has such a template or such a tool. Here is my variant: Usage: glib-gentype [OPTIONS] NAMESPACE LOCALNAME [TypeName] Generates the header file for TypeName. NAMESPACE - namespace of the type, for instance 'GTK' LOCAL_NAME - local name of the type, for instance 'TREE_VIEW' TypeName - optionally the type name, for instance 'GtkTreeView Options: -b, --base=TYPE Base type of the object. Default: GObject. -m, --mode=MODE Operation mode: header or body. Default: header. It lacks property and signal support. Probable 'cause support for such a feature most certainly belongs into the editor?
Duh, this bug was closed as "WONTFIX" already? Cody, your subscription cheated me! :-D Reopen?
Created attachment 267989 [details] [review] gtype: add type declaration macros for headers Add G_DECLARE_DERIVABLE_TYPE() and G_DECLARE_FINAL_TYPE() to allow skipping almost all of the typical GObject boilerplate code. These macros make some assumptions about GObject best practice that mean that they may not be usable with older classes that have to preserve API/ABI compatibility with a time before these practices existed.
Created attachment 267990 [details] [review] GDesktopAppInfo: use G_DECLARE_FINAL_TYPE() Just a small example of the use of the macro with a class that happened to be compatible with the API/ABI that the macro declares. Note that this class was already exposing its class struct without exposing its instance struct and nobody seemed to notice/care, so the fact that the macro also does that has some (small) precedent.
Concerns: - we need to make sure 'static inline' works on MSVC - we won't be able to do big ports of existing code to the new macros because the macros assume that we use the new-style private setup - exporting the class struct from the _FINAL_ variant is convenient but slightly evil
Review of attachment 267989 [details] [review]: ::: gobject/gtype.h @@ +1371,3 @@ + * It is possible to convert a type from using G_DECLARE_FINAL_TYPE() to G_DECLARE_DERIVABLE_TYPE() without + * breaking API or ABI. As a precaution, you should therefore use G_DECLARE_FINAL_TYPE() until you are sure + * <itemizedlist> I don't think this recommendation is useful to have. it does not make sense for applications, for instance. @@ +1372,3 @@ + * breaking API or ABI. As a precaution, you should therefore use G_DECLARE_FINAL_TYPE() until you are sure + * that it makes sense for your class to be subclassed. Once a class structure has been exposed it is not + * <itemizedlist> the documentation should also specify that the get_type() function is going to be the first declaration, so that the versioning or the visibility annotations can work on it. @@ +1385,3 @@ + +/** + * </listitem> I'd probably drop the DERIVABLE from the macro name; types are derivable by default, and FINAL only as an opt-in. @@ +1453,3 @@ + * that it makes sense for your class to be subclassed. Once a class structure has been exposed it is not + * possible to change its size or remove or reorder items without breaking the API and/or ABI. + static inline gboolean MODULE##_IS_##OBJ_NAME (gpointer ptr) { \ there is no G_DECLARE_SUBCLASSED_TYPE. also, there shouldn't be.
I really like this, it would get rid of more stupid boilerplate. Did anyone try it on MSVC?
MSVC 2013 supports a good chunk of C99, so we could probably start thinking about dropping the C89 requirement for everything.
ebassi: Well, this doesn't even *need* C99. without inline this turns into static functions, which still work, even if its not ideal from a code size perspective.
(In reply to comment #13) > Concerns: > > - we need to make sure 'static inline' works on MSVC pretty sure it works, since we use static inline in various places, and it's now part of our toolchain requirements.
*** Bug 617197 has been marked as a duplicate of this bug. ***
(In reply to comment #18) > (In reply to comment #13) > > Concerns: > > > > - we need to make sure 'static inline' works on MSVC > > pretty sure it works, since we use static inline in various places, and it's > now part of our toolchain requirements. Indeed -- I directly tested this the other day before adding it to our toolchain requirements.
Comment on attachment 267989 [details] [review] gtype: add type declaration macros for headers Attachment 267989 [details] pushed as 3b4cb28 - gtype: add type declaration macros for headers
Maybe we want to add G_DECLARE_INTERFACE() too?
(In reply to Alexander Larsson from comment #22) > Maybe we want to add G_DECLARE_INTERFACE() too? G_DECLARE_INTERFACE was added in bug #743939. Seems like everything’s done here; let’s close this.