Ian Lance Taylor <[EMAIL PROTECTED]> writes:
> I've seen this argument before, but I don't entirely believe it. There
> is a lot of autoconf lore that is the result of people reporting
> problems. People then forget just what the problems were. But that
> does not mean that the problems were not real.
Putting on the hat of someone who's recently become interested in some
sort of repository of tricks, fixes, and techniques for highly portable C
programming (among Unix systems, at least; I'm not as interested in
portability to Microsoft, although it would be a nice bonus), I think a
lot of problems arise from the fact that these problems are reported and
fixed and then the original information as to *what* was broken and *why*
this method was used to work around it is then lost.
It would help immensely if, whenever these sorts of portability
modifications are made, they were tied with an entry in documentation,
either in the code or (if a general principle applied to a lot of areas of
autoconf) in developer documentation. Otherwise, down the road, someone
writes something completely new and doesn't have any reference to refer to
to know what constructs to avoid. Searching through autoconf to make sure
that every construct one uses also appears in autoconf somewhere else is
very hit and miss and fallible.
This is just a specific instance of the more general problem, and similar
guidelines for portable C and shell programming for the *users* of
autoconf would be a great resource for all of us who try to write portable
code. That's an even harder problem. autoconf has a consistent standard
to which it attempts portability, namely "every system on which it's
remotely feasible to run autoconf." Writing C code these days to a
similar standard results in code that most people don't want to maintain;
these days, most of the world has gone to ANSI C prototypes, for example.
One question that I've recently really wished I had the answer to is "if I
assume ANSI C and basic POSIX compliance as of circa 1992, what constructs
can I use and which do I still have to avoid or only use conditionally?"
I find this question interesting since I think that's roughly the level of
portability that one can reasonably expect nearly all free software to be
written to, whereas going back to supporting K&R compilers is probably too
much to ask except for those packages that are part of a core bootstrap
environnment (gcc, make, tar, and friends).
I know *some* of the things that level of standard compliance provides me,
such as being able to just say:
#include <stdlib.h>
#include <unistd.h>
without having to do a bunch of header tests in configure and clutter the
code with a bunch of #defines that will never trigger on any platform
within my target audience. But does that level of compliance guarantee me
that, say, the arguments to setvbuf() will never be reversed? Given that
autoconf says this is only true of pre-SVr3 systems, I would assume so,
but I don't actually know.
It may be that there's no good way of getting this information apart from
going out and buying the standards and trying to figure out from there,
but even that isn't sufficient. There are newer systems that *are* (or
claim to be) compliant with those standards, but which have buggy
implementations that still have to be tested for (AC_FUNC_MEMCMP, for
example). And the standards can't tell me about that.
This is a very hard problem overall; I'm not expecting there to be any
easy and simple solution. But it's something that I've started thinking
about whenever reading information about portability, and I have some
distant hope that someday I'll be able to find or help put together at
least some beginning guidelines for this sort of thing.
I know there are many books which have sections on portable programming,
but most of them are (a) extremely basic, (b) not actually any more widely
tested than my own personal experience, which simply isn't broad enough,
(c) distributed in the form of dead trees, making them unavailable for
easy updating as things change, and (d) often don't come with *tests*
(autoconf macros) and *fixes* (alternate implementations, #define/#if
magic, or the like) for the problems.
--
Russ Allbery ([EMAIL PROTECTED]) <URL:http://www.eyrie.org/~eagle/>