Subject: Re: Doxygen generated documentation
To: None <tech-userlevel@NetBSD.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
Date: 05/24/2005 20:59:29
>> (Some time ago I tried to offer fixes for [missing required
>> includes] and was told that [NetBSD does not consider them
>> problems]; more recently someone else reported similar experiences.)
> There are instances where we are not allowed to make headers
> idempotent (assert.h)
Yes, there are a very few such cases. (I cannot think offhand of any
besides assert.h, though there may be another one or perhaps two.) I
would be willing to make an exception for dependencies on such headers,
though I suspect it would be possible to redesign the interfaces so as
to avoid the problem - I'd have to see an example to be sure.
> and others where we cannot make headers self sufficient because of
> namespace pollution issues.
How is it any less namespace pollutive to have <foo.h> break unless
<bar.h> has been included than to have <foo.h> bring in <bar.h> on its
own? In either case, in order to include <foo.h>, the code will have
imposed on it any restrictions and definitions <bar.h> brings.
However, I feel reasonably sure that approximately all such cases can
be redesigned so that <foo.h> does not depend on <bar.h>, but rather on
(say) <bar-internals.h>, which uses implementation-private namespace,
and which <bar.h> also uses. Again, without a specific example to
consider, I have trouble saying more.
> I have seen many examples where programs fail to include required
> headers (such as <signal.h> when using signals), just because it
> happens to work on operating systems that include the kitchen-sink
> when you include a popular header (such as <unistd.h>). This
> include-all approach actually hurts portability.
Only if you do it wrong. To use your example, having <unistd.h>
include <signal.h> is the wrong way. Having <unistd.h> include
<signal-internals.h>, which is also used by <signal.h> but which stays
to reserved namespace and which defines nothing advertised, is the
right way - and does not produce the problem you describe.
To pick a specific example, looking at the <unistd.h> I find at
readiest hand, I see it declares a number of routines which have off_t
in their prototypes. In aid of this, it includes <sys/types.h>.
This is the wrong way, because it means that the user program has
imposed on it everything from <sys/types.h>, even things the program
has no use for and which are unnecessary for unistd.h.
Two right ways come to mind. One would be for unistd.h to include,
say, sys/types-off_t.h, which defines off_t (and which is included
among others by sys/types.h). The other would be for unistd.h to use,
say, __off_t, and include sys/__types.h to get it; sys/types.h would
then include sys/__types.h and add to it a stream of
"typedef __off_t off_t;" and the like. Either way, a program that
#includes unistd.h with nothing before it gets no errors but has its
namespace invaded by neither off_t nor any of the other things from
sys/types.h; if it uses off_t itself, it needs to include something to
define it, but if it doesn't care about off_t (maybe it just uses
dup(), which takes and returns int), it doesn't need to.
That said, in my own tree, I've been fixing such things by adding the
"missing" includes, and ignoring the namespace pollution issue. If
given reason to think NetBSD would be likely to pick up the result, I
would be happy to start doing fix-ups of our includes tree along either
of the above lines - but I have little appetite for doing pointless
work, and if the attitude really is "this is not a problem" rather than
"this is a problem but that is is an unacceptable fix", such work would
be pretty pointless.
/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML email@example.com
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B