Subject: Re: how to avoid API namespace collisions in an ever evolving system
To: NetBSD Userlevel Technical Discussion List <tech-userlevel@NetBSD.ORG>
From: Greg A. Woods <firstname.lastname@example.org>
Date: 08/13/2002 14:06:00
[ On Tuesday, August 13, 2002 at 12:18:39 (+0200), der Mouse wrote: ]
> Subject: Re: CVS commit: basesrc
> > Perhaps a more useful mechanism would be to have a _NETBSD_SOURCE
> > macro, defining which says that you don't want anything introduced
> > after a given date visible. So having determined that your code
> > worked today, you could #define _NETBSD_SOURCE 20020812, and you
> > wouldn't get any nasty surprises from compiling against newer
> > headers.
> That actually is the only suggestion I've seen which I think is
> actually a decent resolution from the coder's point of view.
I think I'd much rather continue to program defensively and make sure
the namespaces used in my applications are unique enough to never
collide with any system supplied library. It's either that or I'll
write very strictly conforming API compliant code for one of the already
widely supported standards (IEEE POSIX, or X/Open, or even just ISO C),
and when/if I need access to system features not allowed by such
standards then I'll put them in a separately compiled system dependent
module that I'll port to every target independently.
> Unfortunately it means the include files are harder to maintain,
> because you have to insert an #if with every new addition.
Most systems have far Far FAR too much complexity in their "standard"
header files already and sometimes much of it seems unnecessary.
NetBSD's headers are no longer any "better" than any of the commercial
That's not to say though that I deplore strict standard APIs or the
mechanisms necessary to support them in any real-world system. As I say
I'm perfectly happy to write to them where possible and then deal with
system dependent APIs on a per-system (and thus per release) basis. As
a result I'll grudgingly accept that real-world systems will often find
it desirable to merge standard API headers with their own system
specific ones and to use conditional compilation features to allow
compile-time separation of the APIs.
However it's one thing to provide a conditional compliation flag that
guarantees a strict standards-compliant API, and quite another to try to
provide a similar set of flags for a moving target. I think the onus is
on the application maintainer for porting system dependent code between
releases of a given target, just as it is for porting system dependent
code between different targets. I.e. for most intents and purposes a
new release of a given system is very much the same as a wholly
different target system.
> I suppose
> it depends on whether you'd rather make things easy on coders at the
> expense of people adding stuff to libc, or conversely.
The coders already have it "easy" with the widely accepted and supported
standard APIs such as IEEE POSIX and X/Open (SuS). It's just that some
coders are "greedy". They often wish to eat their cake and still have
it afterwards. However these days it's not at all difficult to code the
majority of an application to strict POSIX APIs and to put all the
system dependent stuff in one or a very few modules that will have to be
explicitly ported to every target system.
Anyone who's written or maintained any significant body of widely ported
code in the last decade or so should be well accustomed to following the
techniques I oulined in my opening paragraph. Coders and maintainers
must expect namespace collisions and must be prepared to deal with them.
In other words I would fully expect your modules defining and using your
own private 'heapsort' to have to be compiled with -D_POSIX_SOURCE or
something similar since you did not in advance protect the global
namespace of your program with a sure-to-be-unique naming convention.
Greg A. Woods
+1 416 218-0098; <email@example.com>; <firstname.lastname@example.org>
Planix, Inc. <email@example.com>; VE3TCP; Secrets of the Weird <firstname.lastname@example.org>