Subject: Re: Is there a new tcsh source
To: der Mouse <mouse@Collatz.McRCIM.McGill.EDU>
From: Greg Hudson <ghudson@MIT.EDU>
List: current-users
Date: 10/10/1994 12:52:24
My two cents:

> As someone who writes such "private" declarations, I'd like to note
> that it's _not_ "just bad programming".  In my case, at least, it's
> simply that there is no header file I can count on to declare such
> things for me, so it's either use them undeclared (which works in
> only a few instances) or declare them myself.

This is what standards are for.  Generally, your code should assume a
POSIX.1-compliant system (this means not redeclaring library
functions) unless it has some explicit reason to believe otherwise (a
#define, something discovered by a configuration script, etc.).

> Take sys_errlist, for example.  On my NeXT at home, it's in
> <errno.h>, but on the Suns at work, there is no include file (at
> least not under /usr/include) that declares it.

In this case, your code shouldn't be using sys_errlist at all in the
default case; there is a standard function strerror() for this
purpose.  Certainly, on some systems (SunOS being the most important),
strerror() doesn't exist, so for those systems, you can provide your
own strerror() which uses sys_errlist, but at least your code won't
break on systems which are standard.

If you follow these guidelines, your code has the best chance of
working on a new operating system like NetBSD which you didn't have
specifically in mind while writing the code.  Of the programs I've had
experience with, the best-behaved ones under NetBSD were the ones
which used Gnu autoconf and coded closely to the POSIX.1 specification
when in doubt (and when possible).  The number one way those programs
tended to break was declaring sys_errlist, which is easy to correct
using the method mentioned above and autoconf's
AC_HAVE_FUNC(strerror).

For non-POSIX functions (fsync(), bind(), socket(), select(), etc.)
I'm sometimes forced to include simple declarations (not prototypes)
because I have no standard to rely on, and here I admit there is no
good solution except to try to account for all existing systems.

> Or does your definition of "bad programming" include declaring
> things myself because I can't find an include file that declares
> them everywhere I need to have the code build?

The trap here is thinking only about "everywhere I need to have the
code build," and not, "everywhere I might need to build the code in
the future."  As someone who works in a department which is
constantly, narrowly focused on porting their code to today's
platforms rather than making their code portable, I know the costs of
this.

(I'm not, incidentally, interested in making judgments about "bad
programming"; a lot of code which behaves poorly under NetBSD wasn't
necessarily "bad programming" when it was written, but might be
considered "bad programming" now.)