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.
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.