Hello,
On Fri, 1 Jan 2021, Christian Jullien wrote:
First, happy new year all.
To you as well.
Porting tcc on *BSD systems raised issues/questions with stddef.h from tcc
distrib.
First, it contains a mix of definitions coming from both stddef.h and
stdint.h IMHO it should only contain what stddef.h is supposed to contain.
First some background. TLDR: patches welcome :)
Standard headers are a bit complicated when considering the C library and
the C compiler in isolation (which we need to do with TCC, as we provide
only a compiler). Both are part of a standard describing the whole
implementation, of library and compiler. But some header facilities can
be usefully provided only with compiler knowledge. There's the concept of
free-standing implementations, that need to provide only a few headers
(<stddef.h> being one), and it's such that in those headers are the most
compiler specifics. So it's sensible to provide them with the compiler,
not with the C library (and if only for the reason that if you don't even
have a C library that you can use the free-standing part of the C
standard).
You will notice that also GCC provides it's own <stddef.h>.
<stdint.h> is a mixed bag; most of it's facilities can be nicely defined
without many compiler specifics except very few crucial macros/builtins.
So, many C libraries do in fact provide that header themself, but still in
a way that there are compilers that don't work correctly with them. E.g.
GCC provides a <stdint.h> that uses the library one with a hosted
implementation (the opposite of a free-standing one).
There's also an advantage for the C library providing these headers: they
can in addition to the standard facilities also provide means that are
specific to the library implementation (e.g. the whole _GNU_SOURCE
business in the GNU C library).
So, for some headers there's a grey zone for decisions: should the
compiler or the library provide a header. For <stddef.h> it's easy: also
other system compilers provide it, e.g. also because of the offsetof()
macro that needs compiler support when you want to avoid non-portable
implementations, so TCC should provide it. For <stdint.h>: here it's less
clear: TCC doesn't claim to provide a free-standing implementation, so it
doesn't _have_ to provide it, but could rely on the C library, which we do
right now.
But of course you are right in that the TCC <stddef.h> should not provide
anything that it isn't supposed to provide, as that can cause conflicts
like you are seeing.
Several solutions:
a) make the non-standard extensions of TCC <stddef.h> be conditional on a
macro (or a non-existence of a macro, like e.g. it could continue to
provide them outside C89/C99/C11 conformance).
b) remove those additions completely
c) b + provide own <stdint.h>
d) b + leave it to the C library to provide <stdint.h>
The nicest solution would be (c) as that goes towards providing a
free-standing implementation. But the provided <stdint.h> needs to be
compatible with anything the C libraries provide or rely on. GCC has to
jump through hoops with that (using include_next), that might be historic
cruft, or it might still be for a reason, I don't know. So without trying
on a range of platforms I can't say if (c) is realistic or not.
Why tcc needs its own stddef.h instead of system one?
See above, the system one also is compiler specific.
Why tcc does not need stdint.h?
Because we got away with it :) Patches welcome.
I suppose it is because tcc does not support all gcc syntaxes found on
stddef.h (is it still true?) in that case, it would be better to split
definitions in stddef.h and stdint.h following the ISO C11 standard.
Ciao,
Michael.
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel