Search code examples
cglib

Could someone explain this macro #define g_once_init_enter(location) which is in glib for me?


I got a little confused when I read this macro : #define g_once_init_enter(location) which is defined in glib library.

#define g_once_init_enter(location)                            \
  (G_GNUC_EXTENSION({                                          \
  G_STATIC_ASSERT(sizeof *(location) == sizeof(gpointer));     \
  (void) (0 ? (gpointer) *(location) : 0);                     \
  (!g_atomic_pointer_get (location) &&                         \
  g_once_init_enter (location));                               \
}))

what's the effect of this line :(void) (0 ? (gpointer) *(location) : 0); and the last line is g_once_init_enter(location) again, is it a dead loop? Thanks for your reply.


Solution

  • This looks like an implicit type check to me.

    The macro obviously expects to be passed the address of a gpointer (whatever that is), but macros don't have argument types, so it can't say that.

    Instead it asserts that sizeof *(location) is the same as sizeof(gpointer), which verifies that location can be dereferenced and that what it's pointing to has the right size (otherwise that G_STATIC_ASSERT line wouldn't compile).

    Then it makes sure that whatever (location) is pointing to can be converted to gpointer, by compiling the cast (gpointer) *(location). This line has no other effect (and the cast is never reached at runtime); it's only there to make the compiler complain if the cast is somehow invalid.

    Macros aren't expanded recursively. The last line, g_once_init_enter(location), is left as-is, so there must be an actual g_once_init_enter function somewhere that can be called here.