public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* GCC's <assert.h> and C99
@ 2000-09-16  2:19 Joseph S. Myers
  2000-09-16  3:21 ` Martin Buchholz
  0 siblings, 1 reply; 9+ messages in thread
From: Joseph S. Myers @ 2000-09-16  2:19 UTC (permalink / raw)
  To: gcc; +Cc: martin

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

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: GCC's <assert.h> and C99
  2000-09-16  2:19 GCC's <assert.h> and C99 Joseph S. Myers
@ 2000-09-16  3:21 ` Martin Buchholz
  2000-09-21 13:03   ` Kamil Iskra
  0 siblings, 1 reply; 9+ messages in thread
From: Martin Buchholz @ 2000-09-16  3:21 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc

>>>>> "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)
#else
#define __assert(expression, file, line)  \
  (__eprintf ("%s:%u: failed assertion `%s'\n",		\
	      file, line, expression), 0)
#endif

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.

Martin

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: GCC's <assert.h> and C99
  2000-09-16  3:21 ` Martin Buchholz
@ 2000-09-21 13:03   ` Kamil Iskra
  2000-09-21 17:31     ` Martin Buchholz
  0 siblings, 1 reply; 9+ messages in thread
From: Kamil Iskra @ 2000-09-21 13:03 UTC (permalink / raw)
  To: Martin Buchholz; +Cc: gcc

On Sat, 16 Sep 2000, Martin Buchholz wrote:

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

Out of curiosity:

Could you explain, why you get these undefined references? IIRC, __eprintf
is defined in libgcc.a. You are always supposed to link with -lgcc when
linking .o objects generated with GCC. So why is __eprintf undefined?

-- 
/ Kamil Iskra  kamil@wins.uva.nl                                          \
| Section Computational Science, Faculty FNWI, Universiteit van Amsterdam |
| tel. +31 20 525 75 35  fax. +31 20 525 74 90                            |
\ Kruislaan 403  room F.202  1098 SJ Amsterdam (NL)                       /


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: GCC's <assert.h> and C99
  2000-09-21 13:03   ` Kamil Iskra
@ 2000-09-21 17:31     ` Martin Buchholz
  2000-09-21 19:17       ` Zack Weinberg
  0 siblings, 1 reply; 9+ messages in thread
From: Martin Buchholz @ 2000-09-21 17:31 UTC (permalink / raw)
  To: Kamil Iskra; +Cc: gcc

>>>>> "K" == Kamil Iskra <kamil@wins.uva.nl> writes:

K> On Sat, 16 Sep 2000, Martin Buchholz wrote:
>> 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.

K> Out of curiosity:

K> Could you explain, why you get these undefined references? IIRC, __eprintf
K> is defined in libgcc.a. You are always supposed to link with -lgcc when
K> linking .o objects generated with GCC. So why is __eprintf undefined?

No, you are ____NOT_____ supposed to.

C is a multiple-compilation-unit language.

Imagine if the authors of *other* compilers insisted on using their
compilers to link their object code.  You'd never be able to use gcc
on commercial Unix systems.

As I said earlier in a thread on bug-gcc:


>>>>> "AO" == Alexandre Oliva <aoliva@redhat.com> writes:

AO> On Jun 26, 2000, Martin Buchholz <martin@xemacs.org> wrote:
>> Think about what you're saying.  The policy of requiring libgcc for
>> the C linking stage is an *exclusionary* one.

AO> Why?  You can always have libgcc and link it with your programs, even
AO> when you're linking using a proprietary toolchain.

Library author A wants to create a portable library.  Writes it in C.
Distributes libFOO.1.0.0.tar.gz

Binary packager B works at MegaCorp.com and would like to make the
latest version of libFOO.a available to everyone working at MegaCorp.
Because B is secretly a free software zealot, B uses entirely free
software, including gcc, to create libFOO.a and places the updated copy
in /freeware/lib, which is NFS mounted by all computers at the
company.  B tests libFOO.a carefully using the usual toolbox of free
software.  B announces libFOO.a on a company-wide web site.

Later, complaints come in from all over MegaCorp that builds are
breaking.  For some reason, there's this unresolved symbol __eprintf
in libFOO.a.  Where did that come from?  Didn't anybody test the new
library?  Many users at MegaCorp, traditionally distrustful of free
software, use the vendor compiler, which "always just works".  They
trace the link failure back to libFOO.a and packager B.

B loses his job at MegaCorp and his devotion to free software.  The
developers of MegaCorp see what happens when you start playing with
free software.  The CIO of MegaCorp sends out a memo forbidding the
use of gcc.  B never goes on to become a future gcc developer.

That's why you want assert() not to depend on libgcc.

AO> Therefore, aiming at a libgcc-independent GCC is much more work than
AO> you might think.

I'd be happy with a GCC that creates libgcc-independent code for most
real-world libraries on most popular Unices, most prominently Solaris.
Far from being a lot of work, fixing assert() will cause most of the
problems to go away.

>> When compiling with -Omake-it-fast-not-portable, you can call the
>> external __eprintf from libgcc.

AO> __eprintf is the simplest of the problems.  You can always compile
AO> with -DNDEBUG to get rid of calls to it :-)

I am concerned not with my own build problems, but with the fate of my
friend B above...

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: GCC's <assert.h> and C99
  2000-09-21 17:31     ` Martin Buchholz
@ 2000-09-21 19:17       ` Zack Weinberg
  2000-09-23  0:07         ` Martin Buchholz
  0 siblings, 1 reply; 9+ messages in thread
From: Zack Weinberg @ 2000-09-21 19:17 UTC (permalink / raw)
  To: Martin Buchholz; +Cc: gcc

You were told, months ago, that the proper way to fix the __eprintf problem
- yes, we accept that it is a problem - is to submit a two line patch for
the target Makefile fragment for the systems you care about (e.g. t-svr4):

+# Use the system <assert.h>.
+INSTALL_ASSERT_H =

Alternatively, you could write a clever autoconf test which determines if
the target has a C89 compliant <assert.h> and disables installation of our
header if it does.  That would fix the problem for everyone, but would be
substantially harder.

Why have you not done either of these things?

...
As to the issue of C99 requiring the appearance of the function name in the
string printed by a failed assertion - I submit that this is a library issue
and we should not worry about it.  Note that assert.h is not required to be
provided by a freestanding implementation of C in either C89 or C99.  (And
that argues that we should not provide it on any system, even if it's
pre-C89...)

zw

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: GCC's <assert.h> and C99
  2000-09-21 19:17       ` Zack Weinberg
@ 2000-09-23  0:07         ` Martin Buchholz
  2000-09-23 15:08           ` Zack Weinberg
  0 siblings, 1 reply; 9+ messages in thread
From: Martin Buchholz @ 2000-09-23  0:07 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: gcc

>>>>> "ZW" == Zack Weinberg <zack@rabi.columbia.edu> writes:

ZW> You were told, months ago, that the proper way to fix the __eprintf problem
ZW> - yes, we accept that it is a problem - is to submit a two line patch for
ZW> the target Makefile fragment for the systems you care about (e.g. t-svr4):

ZW> +# Use the system <assert.h>.
ZW> +INSTALL_ASSERT_H =

I don't believe in adding more stuff to system-specific files.  Of
course, gcc is bound to be non-portable, but still one should try hard
to autoconfiscate everything.

ZW> Alternatively, you could write a clever autoconf test which determines if
ZW> the target has a C89 compliant <assert.h> and disables installation of our
ZW> header if it does.  That would fix the problem for everyone, but would be
ZW> substantially harder.

Hmmmmm.

ZW> Why have you not done either of these things?

Maybe because I'm busy maintaining my own amazingly buggy free
software.  

I *did* submit a patch in the area of assert/eprintf.  I have heard no
response from the gcc folks, although a parallel patch to libc made it
into the sources.

ZW> ...
ZW> As to the issue of C99 requiring the appearance of the function name in the
ZW> string printed by a failed assertion - I submit that this is a library issue
ZW> and we should not worry about it.  Note that assert.h is not required to be
ZW> provided by a freestanding implementation of C in either C89 or C99.  (And
ZW> that argues that we should not provide it on any system, even if it's
ZW> pre-C89...)

Zack, that's a very enlightening comment.  I had assumed that gcc came
with assert.h because it could not be done just as well by a libc.

Offhand, it looks hard for a libc implementor to provide an assert.h
that works for both c89 and c9x without compiler-specific hacks.  How
do you test for support for __func__?

The implementor of glibc naturally provided special support for gcc,
like this:

# ifdef __GNUC__
#  if __GNUC__ > 2 || (__GNUC__ == 2 \
		       && __GNUC_MINOR__ >= (defined __cplusplus ? 6 : 4))
...

Martin

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: GCC's <assert.h> and C99
  2000-09-23  0:07         ` Martin Buchholz
@ 2000-09-23 15:08           ` Zack Weinberg
  0 siblings, 0 replies; 9+ messages in thread
From: Zack Weinberg @ 2000-09-23 15:08 UTC (permalink / raw)
  To: martin; +Cc: Zack Weinberg, gcc, zack

On Sat, 23 Sep 2000 16:06:45 +0900 (JST), Martin Buchholz wrote:
>>>>>> "ZW" == Zack Weinberg <zack@rabi.columbia.edu> writes:
>
>ZW> You were told, months ago, that the proper way to fix the __eprintf proble
>m
>ZW> - yes, we accept that it is a problem - is to submit a two line patch for
>ZW> the target Makefile fragment for the systems you care about (e.g. t-svr4):
>
>ZW> +# Use the system <assert.h>.
>ZW> +INSTALL_ASSERT_H =
>
>I don't believe in adding more stuff to system-specific files.  Of
>course, gcc is bound to be non-portable, but still one should try hard
>to autoconfiscate everything.

Yes, autoconfiscating everything is desirable, but at the moment the above
is the only option we have.  It works, it's the documented solution to your
problem, it's two lines of code.

>ZW> Alternatively, you could write a clever autoconf test which determines if
>ZW> the target has a C89 compliant <assert.h> and disables installation of our
>ZW> header if it does.  That would fix the problem for everyone, but would be
>ZW> substantially harder.
>
>Hmmmmm.

I'll get you started - there's a suitable test program at the end of the
message.

The tricky bit will be compiling and linking it with the target headers. 
You'll have to postpone the test until after the compiler has been built,
and disable it if inhibit_libc is defined (in that case, assume the libc to
be built will provide a good copy of the header).

>ZW> Why have you not done either of these things?
>
>Maybe because I'm busy maintaining my own amazingly buggy free
>software.  

It'd take you less brain time to generate and test the above two line patch
than it would to complain about the current situation so loudly.

>Offhand, it looks hard for a libc implementor to provide an assert.h
>that works for both c89 and c9x without compiler-specific hacks.  How
>do you test for support for __func__?

#if defined __STDC_VERSION__ && __STDC_VERSION__ > 199901L
/* we have __func__ */
#endif

zw

-- test-assert.c --
/* Test as much of assert() as can be tested without running a program.
   This program should link if compiled with -DNDEBUG, and fail to link
   without, but should get no compiler failures in either case.  */

extern int predicate (void);

#include <assert.h>

int main(void)
{
  assert (predicate ());
  return 0;
}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: GCC's <assert.h> and C99
  2000-09-22 12:56 Mike Stump
@ 2000-09-22 23:38 ` Martin Buchholz
  0 siblings, 0 replies; 9+ messages in thread
From: Martin Buchholz @ 2000-09-22 23:38 UTC (permalink / raw)
  To: Mike Stump; +Cc: kamil, gcc

>>>>> "MS" == Mike Stump <mrs@windriver.com> writes:

>> Date: Fri, 22 Sep 2000 09:31:14 +0900 (JST)
>> From: Martin Buchholz <martin@xemacs.org>
>> To: Kamil Iskra <kamil@wins.uva.nl>
>> Cc: gcc@gcc.gnu.org

>> Imagine if the authors of *other* compilers insisted on using their
>> compilers to link their object code.  You'd never be able to use gcc
>> on commercial Unix systems.

MS> ?  They do have libraries and files that they do require one to link
MS> with.  Yet, that doesn't mean that we can't link in those files.

? You mean files like libc.a, crt0.o ?

>> That's why you want assert() not to depend on libgcc.

MS> Just as other systems have various support libraries and files that
MS> support their compiler, we have some files and libraries to support
MS> ours.  The situation is actually symmetric.

Not really.  Other compilers require things that are part of the
operating system, not part of the compiler.  FOO.a files should not
have any dependencies on things not explicitly mentioned by the user
on the link command line.

E.g. if you create libfoo.a like this

gcc foo.c bar.c -o libfoo.a -lfrob

then a user of libfoo.a (years later) is required to have a libfrob
around when linking libfoo.a into some application.  But requiring an
underdocumented libgcc is going too far.

MS> People are free to prelink and resolve those dependencies, if they
MS> wish.  If they should, and choose not to, that is their fault.  In
MS> this case, it would be B's fault for being incompetent, and yes,
MS> incompetent people like B should be fired, or at least re-educated.

You really like your software to be user-hostile, eh?

>> I'd be happy with a GCC that creates libgcc-independent code for most
>> real-world libraries on most popular Unices, most prominently Solaris.
>> Far from being a lot of work, fixing assert() will cause most of the
>> problems to go away.

MS> :-) Well, no, not really.  It will just hack-around one example of a
MS> requirement the compiler has.  That requirement is that you expose
MS> libgcc.a to the linker in some fashion.  Failure to do that, is using
MS> the tools in a way that we don't intent.

>> I am concerned not with my own build problems, but with the fate of my
>> friend B above...

MS> If you are concerned, help us re-educate him.

That's the wrong answer.  

But this is deeply philosophical, so let's end the direction this
thread is heading.

MS> One can include all those .o files from libgcc.a that have symbols
MS> that any of their .o files in their library depend upon, in they
MS> library.  When one builds a shared library, one can link two versions
MS> of it, one with libgcc.a and one with out, and advise people that are
MS> going to use other compilers to link to use the prelinked version, and
MS> those that will use gcc to link, can just use the normal version.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: GCC's <assert.h> and C99
@ 2000-09-22 12:56 Mike Stump
  2000-09-22 23:38 ` Martin Buchholz
  0 siblings, 1 reply; 9+ messages in thread
From: Mike Stump @ 2000-09-22 12:56 UTC (permalink / raw)
  To: kamil, martin; +Cc: gcc

> Date: Fri, 22 Sep 2000 09:31:14 +0900 (JST)
> From: Martin Buchholz <martin@xemacs.org>
> To: Kamil Iskra <kamil@wins.uva.nl>
> Cc: gcc@gcc.gnu.org

> Imagine if the authors of *other* compilers insisted on using their
> compilers to link their object code.  You'd never be able to use gcc
> on commercial Unix systems.

?  They do have libraries and files that they do require one to link
with.  Yet, that doesn't mean that we can't link in those files.

> That's why you want assert() not to depend on libgcc.

Just as other systems have various support libraries and files that
support their compiler, we have some files and libraries to support
ours.  The situation is actually symmetric.

People are free to prelink and resolve those dependencies, if they
wish.  If they should, and choose not to, that is their fault.  In
this case, it would be B's fault for being incompetent, and yes,
incompetent people like B should be fired, or at least re-educated.

> I'd be happy with a GCC that creates libgcc-independent code for most
> real-world libraries on most popular Unices, most prominently Solaris.
> Far from being a lot of work, fixing assert() will cause most of the
> problems to go away.

:-) Well, no, not really.  It will just hack-around one example of a
requirement the compiler has.  That requirement is that you expose
libgcc.a to the linker in some fashion.  Failure to do that, is using
the tools in a way that we don't intent.

> I am concerned not with my own build problems, but with the fate of my
> friend B above...

If you are concerned, help us re-educate him.

One can include all those .o files from libgcc.a that have symbols
that any of their .o files in their library depend upon, in they
library.  When one builds a shared library, one can link two versions
of it, one with libgcc.a and one with out, and advise people that are
going to use other compilers to link to use the prelinked version, and
those that will use gcc to link, can just use the normal version.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2000-09-23 15:08 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-09-16  2:19 GCC's <assert.h> and C99 Joseph S. Myers
2000-09-16  3:21 ` Martin Buchholz
2000-09-21 13:03   ` Kamil Iskra
2000-09-21 17:31     ` Martin Buchholz
2000-09-21 19:17       ` Zack Weinberg
2000-09-23  0:07         ` Martin Buchholz
2000-09-23 15:08           ` Zack Weinberg
2000-09-22 12:56 Mike Stump
2000-09-22 23:38 ` Martin Buchholz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).