kre at munnari.OZ.AU
Thu Aug 5 13:03:35 UTC 2004
Date: Thu, 5 Aug 2004 07:38:17 +0100
From: "Clive D.W. Feather" <clive at demon.net>
Message-ID: <20040805063817.GC22268 at finch-staff-1.thus.net>
| However, I'd rather that the year field said "0097" and not " 97", so that
| some idiot doesn't think the latter means 1997.
I'm not sure that there's enough difference there to matter, but this
isn't important enough to argue about.
| Even with that limitation you have problems. There were just too many
| places where pre-Standard compilers differed and the Standard had to make a
| choice one way or the other.
Those cases I don't worry about - portable code simply has to avoid
any such usages, or it isn't portable (either avoid them, or do some
kind of compile (or run) time feature test, and work out what works
on the particular system in question).
The standard may have blessed one of the previous implementation choices,
or come up with some entirely new way that seems better than any of the
earlier ones, or ... That's all fine in a case like this.
A truly portable program however simply ignores the standard, it has to,
at least until all evidence suggests that no old systems remain, anywhere
at all, where they might cause a problem.
Programs that don't care as much about true portability can simply have
a README (or whatever) that says "a C99 implementation is required for
| While asctime() may not be a good example,
For the point I am trying to make, asctime() is the prefect example.
This isn't a case where there were different implementations doing
different things, that needed to be rationalised. There was no
requirement that anything be changed.
What there was however was a (hopelessly) inadequate interface,
almost everything about it is (was) inadequate (its inability to
handle anything other than years that can be represented in 4 characters,
the use of the static buffer, ...).
When that situation arises, the worst thing a standards body can do is
to succumb to the temptation to "fix" the interface, or as in this
case, attempt to partially fix it.
All that means is that now old code, that had been working with the
old interface (apparently adequate for the old code's needs) can no
longer trust the function, as some new compilers might have it do
something different than what it has always done before.
New code still shouldn't go near this interface, as to keep it even
seemingly compatible with what previously existed, it must remain
largely inadequate (so the static buffer in asctime cannot be "fixed").
The end result is that we end up with a standards blessed function that
is absolutely useless for everyone.
I can kind of live with ado's last suggested patch around this issue,
though I would really much prefer there was no #if to generate the
"standards conforming" version of asctime. Simply existing that way
does no harm, the problem is that someone might not understand what is
happening, and believe that turning on that behaviour is actually the
better choice to make. If that happens and the resulting code gets
distributed anywhere, then asctime has just turned into yet another of
those "any code that uses this is broken by definition" functions that
we (unfortunately) have too many of already.
So, I'd prefer just the "always fixed width field" version of asctime,
the way the old interface was defined - I'd prefer it generate "YYYY"
for the year field than "10000" (or anything else) - as long as it
remains 4 characters wide - always.
More information about the tz