This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[EXPERIMENTAL PATCH] Replace __eprintf with __assert


If we replace the call to __eprintf in assert() with a call to a
function __assert(), the binary compatibility problem reported in

http://gcc.gnu.org/ml/gcc-bugs/2000-06/msg00583.html

is fixed.

The reason the problem is fixed is that this implementation of
__assert is binary compatible with the implementation in libc.a on two
platforms I tested, Sun Solaris 2.6 and DEC OSF 4.0E.

This patch also has the advantage that the code generated by gcc is
more efficient!  Functions calling assert have smaller object code,
leading to better cache behavior.  The string

"%s:%u: failed assertion `%s'\n"

is not needlessly duplicated in every .o file that calls assert().
Also, in the future this message can be more easily translated for NLS.

__eprintf needs to stay in libgcc, at least for a while, for binary
compatibility with pre-patch versions of gcc.

A final implementation needs to test for the presence of __assert()
and perhaps other implementation-specific symbols in libc at configure
time, and choose an appropriate assert.h based on that.

When building libraries with post-patch gcc and linking with cc, you
get the __assert() in libc.  When building libraries with cc and
linking with post-patch gcc, you get the __assert() in libgcc.a.  When
building libraries with pre-patch gcc and linking with post-patch gcc,
you get the __eprintf in post-patch libgcc.a.  When building libraries
with post-patch gcc and linking with pre-patch gcc, you get the
__assert in libc.a (this is why a configure test is necessary in a
fully correct implementation).

Although the generated binaries may print different abort messages,
the behavior should be equivalent otherwise.

If this patch is accepted in principle, some more work needs to be
done (in the implementation below, assert is in __eprintf.o, while it
really should be in its own __assert.o).

Index: ./gcc/assert.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/assert.h,v
retrieving revision 1.3
diff -u -w -r1.3 assert.h
--- assert.h	1998/12/16 20:53:29	1.3
+++ assert.h	2000/06/27 01:07:36
@@ -23,31 +23,23 @@
 /* Defined in libgcc.a */
 #ifdef __cplusplus
 extern "C" {
-extern void __eprintf (const char *, const char *, unsigned, const char *)
+extern void __assert (const char *, const char *, unsigned)
     __attribute__ ((noreturn));
 }
 #else
-extern void __eprintf (const char *, const char *, unsigned, const char *)
+extern void __assert (const char *, const char *, unsigned)
     __attribute__ ((noreturn));
 #endif
 
 #define assert(expression)  \
   ((void) ((expression) ? 0 : __assert (#expression, __FILE__, __LINE__)))
 
-#define __assert(expression, file, line)  \
-  (__eprintf ("%s:%u: failed assertion `%s'\n",		\
-	      file, line, expression), 0)
-
 #else /* no __STDC__ and not C++; i.e. -traditional.  */
 
-extern void __eprintf () __attribute__ ((noreturn)); /* Defined in libgcc.a */
+extern void __assert () __attribute__ ((noreturn)); /* Defined in libgcc.a */
 
 #define assert(expression)  \
   ((void) ((expression) ? 0 : __assert (expression, __FILE__, __LINE__)))
-
-#define __assert(expression, file, lineno)  \
-  (__eprintf ("%s:%u: failed assertion `%s'\n",		\
-	      file, lineno, "expression"), 0)
 
 #endif /* no __STDC__ and not C++; i.e. -traditional.  */
 #endif /* no __GNU__; i.e., /bin/cc.  */
Index: ./gcc/libgcc2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/libgcc2.c,v
retrieving revision 1.96
diff -u -w -r1.96 libgcc2.c
--- libgcc2.c	2000/06/13 23:36:18	1.96
+++ libgcc2.c	2000/06/27 01:07:43
@@ -1311,6 +1311,14 @@
   abort ();
 }
 
+void
+__assert (const char *expression, const char *filename, unsigned int line)
+{
+  fprintf (stderr, "%s:%u: failed assertion `%s'\n", filename, line, expression);
+  fflush (stderr);
+  abort ();
+}
+
 #endif
 #endif
 

ObLegal:  I hereby place this message in the public domain.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]