GCC's <assert.h> and C99

Martin Buchholz martin@xemacs.org
Sat Sep 16 03:21:00 GMT 2000

>>>>> "JSM" == Joseph S Myers <jsm28@cam.ac.uk> writes:

JSM> C99 requires assertion failure messages from <assert.h> to include the
JSM> name of the current function as well as the file name and line number.

I didn't think about that when I posted previously.  This makes the
binary compatibility problem more interesting.

To avoid a world of binary compatibility pain that will last for a
decade, I suggest that the gcc team attempt to NOT define a new
__assert variant for inclusion in gcclib for C99.

This can be done by some tricks like (this is non-working code):

#ifdef C99
#define __assert(expression, file, line)  \
  (__eprintf ("%s:%u: failed assertion `%s' in function `"__FUNCTION__"' \n", \
	      file, line, expression), 0)
#define __assert(expression, file, line)  \
  (__eprintf ("%s:%u: failed assertion `%s'\n",		\
	      file, line, expression), 0)

JSM> GCC's <assert.h> doesn't do this.  Would it be appropriate to fix this by
JSM> adding a new __eprintf2 function that takes this information and adjusting
JSM> assert.h accordingly?  Or, it was suggested by Martin Buchholz
JSM> <martin@xemacs.org> that GCC should be using a SysV ABI function __assert
JSM> instead of __eprintf, but this function does not allow for inclusion of
JSM> the function name, so given C99 it would seem a bad idea to move to
JSM> __assert now.  Is there a corresponding replacement for __assert in the
JSM> ABI which does support C99?  If so, it would be appropriate to use that.

Avoid changes that require external ABI changes at all costs.


Having thought about the problem of binary compatibility for a while
now, I am more in favor now of the simple solution:

The only reliable thing to do is to include a copy of __eprintf or
__assert (either pre- or post-C99) in every .o file that calls
assert().  As I've pointed out in earlier email, __eprintf is stupidly
wasteful, compared to __assert, for no reason.  We can simultaneously
eliminate the wastefulness of __eprintf, and introduce the new
wastefulness of having a separate copy of __assert in every applicable
.o file, and then at least assert will JUST WORK.  Of course, the gcc
team provides an obscure -fuse-gcclib-eprintf flag for those who need
the extra 89 (?) bytes in their .o files.  Maybe the gcc team knows
how to trick the linker into discarding all but one of the __assert
functions.  A stupid space optimization hack could be added to GNU ld
just for assert.

To summarize the problem: You would like to be able to use .o and .a
files compiled and or linked by different compilers (gcc and non-gcc,
pre- and post-C99), and never get a link error due an unreferenced
function (e.g. __eprintf) that you've never heard of.


More information about the Gcc mailing list