unit testing and G_INLINE_FUNC - breakage moving from 2.4 to 2.6



In some software we are writing we use glib pretty much everywhere, and
G_INLINE_FUNC to manage all of our inline functions. We're just trying
to upgrade from glib 2.4.8  to glib 2.6.6, and the change from "static
inline" to "extern inline" has exposed some bugs in our code/glib.

We have headers, which declare inline functions, and then provide a
definition marked G_INLINE_FUNC. We have corresponding .c files which
define G_IMPLEMENT_INLINES and then include the .h file. We have tests
which include some header functions for the test, #define some standard
library functions to refer to hooked versions, include the .c file (so
gcov will see it), and go on to do test stuff.

Building against 2.6.6, these tests fail to build, with unresolved
references to the inline functions. The tests are built without
optimization, gcc doesn't inline functions with optimization disabled,
"extern inline" tells gcc to never make a non-inline version of the
function, and the definition of G_INLINE_FUNC is fixed when glib.h is
first encountered, which is before G_IMPLEMENT_INLINES was set.

The non-G_IMPLEMENT_INLINES definition of G_INLINE_FUNC used to be
static inline, which told gcc to only make a non-inline version if
necessary, and make it a local symbol (which works okay, unless your
inline function uses a static variable and you are linking together
files that got different versions, I guess).


I've gotten a few tests to build by G_INLINE_FUNC to be empty
before including the .c file. Another approach would be moving the
include of the .c file up to the top of the test, so G_IMPLEMENT_INLINES
is set from the beginning, but that's not entirely foolproof either
because it might break if we need to link a test together from a few
source files that all try this trick.

Another option would be redefining G_INLINE_FUNC to pick up the value of
G_IMPLEMENT_INLINES at the point of use rather than where glib is first
included. Something like this seems to behave, as long as you
only define G_IMPLEMENT_INLINES to be 1 or empty

#define G_INLINE_FUNC GIF_DELAY(G_IMPLEMENT_INLINES)
#define GIF_DELAY(X) GIF_TEST(X)
#define GIF_TEST(X) GIF_##X
#define GIF_1 extern inline
#define GIF_ extern inline
#define GIF_G_IMPLEMENT_INLINES
(GIF_DELAY is to get around some wierdness in the behaviour of ##).

Is there any standard way of writing and unit testing code that avoids
this problem?

Brandon




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