ralph said:
[...]
As Mr. Thompson pointed out the closest to an "official" date would be
C89, however K&R fell out of common use long before that. Most C
compilers I used by the early 80s offered vendor specific
implementations that supported the "ANSI style", though there wasn't
any official 'ANSI' yet.
You encountered "ANSI style" compilers in the "early 80s?" Six,
seven, eight years before the Standard became final? That's some
pretty impressive tea-leaf reading ...
I can appreciate your disbelief especially if one might be used to
today's environment where the usual process is to develop a "standard"
and then sit back and watch various vendors move to support the new
standard.
Such was not the case with C. In computer-years an official 'standard'
was a long, long time coming. I started using C in 1977 (a year before
they published the book. <g>) There wasn't a 'Standard' till 1986.
That was almost 10 years since I started, and ~15 years after it was
invented.
Do you seriously believe the vendors sat still all that time waiting?
I tried to be very careful and use the expressions "ANSI style",
"ANSI-Compatibility" in quotes, because as a side issue I'm not sure
when we started applying the term "ANSI". If memory serves we used to
call the extensions "Standard C" as opposed to "K&R C".
The Standard was a moving target during most of its development.
The first draft I read included the `noalias' keyword -- and that was
in 1988, only about twenty months before ANSI's formal adoption! Did
the compilers you recall support `noalias'?
Wasn't so much a "moving target" as a classic battle between those who
wanted the standard to agree with the existing implementations at the
time, and those who wanted to define an "even better" language.
Thankfully, the "implementers" pretty much won out. C86 added little
that wasn't already out there.
The "-noalias" option was one of the latter ideas. Don't know if I
ever used a compiler that offered that keyword. I only know I never
used it. I vaguely remember it as an optimizing option, but believe it
applied to whole code blocks not to any one variable.
[Sidnote: I probably wouldn't use it now that I took the time to look
it up. I remember too well the lesson learned with the 'register'
keyword. I jumped on that bandwagon after reading the specs when it
first showed up. Spending time 'n effort to pre-think ways to make my
code more efficient - only to discover that most compiles ignored it
or placed candidates in the register anyway. <g> I seldom bother
anymore, unless testing demonstrated it as needed in a critical
section. Again, no point in anyone flaming me, just my opinion.]
Ben's experience matches mine, but it wasn't a reluctance to
upgrade compilers that motivated us to keep using old style: It was
the large body of existing old-style code, and the certainty that
we would introduce gratuitous bugs in the course of a translation
effort. For some strange reason, our engineering management was not
highly motivated to expend programming and Q/A effort on a project
that would have no customer-visible effect except new bugs ...
We used ANSI-capable compilers to process our K&R-style code.
On some platforms we had to implement work-arounds to get pre-ANSI
effects from an ANSI compiler, just so our pre-ANSI code would continue
to work as it had.
That is interesting and once again points to the vast differences in
experience and what I might call one's "world view".
I was generally a contract programmer. I was never placed in a
situation where I had to deal with humongous amounts of legacy code.
It was either to add some functionality - in which case I just adopted
whatever 'style' was currently in use, or more common totally new
projects - in which case I used whatever I liked, and I liked
vendor-extensions.
You might add to that (at the definite risk of starting another
flame-war <g>) I have never been a big believer in "portable code".
That is, never a slave to the idea that what I wrote needed to be
portable to a vast array of various operating systems. UNLESS it was
business requirement that it compile and run on multiple OS's. I also
'liked' platform-specific extensions. Especially as in most cases
there was a good reason they were available.
I wrote for the target at hand with the best tools available.
Like I said before - the few situations where differences were
substantial, ie, demanded to be addressed - I often fell back on
conditional compiles and even re-writing whole blocks of code. Better
an application performs to its best on all required platforms.
I always felt adhering to "K&R C" as some kind of "lowest common
denominator" was a silly limitation dreamed up by code lawyers sitting
in a committee with nothing else to do. <g>
But I don't argue with those who do. They have a point. If they are
signing the check then I'll even agree with them... till the next job.
[As a side note. (As though I haven't stirred up enough trouble. <g>)
I never been a big fan of an, or make that THE "enterprise" compiler.
I feel using one through out a single or suite of projects makes
obvious sense. But to delay moving on to something better for a round
of new projects makes more sense. There is no reason to keep using
SmithC v3 just because you wrote your applications with it 5 years
ago.
Of course if SmithC v3 still works just fine, then keep it. I'm NOT
advocating moving on just because something is new, only if new
translates to "better" for your business requirements.
Keep SmithC around for the legacy stuff.]
But again, that likely depends on one's experience and comfort level.
As a contractor I became very used to using multiple compilers on
different boxes at the same time. Never expected the same code to work
exactly the same everywhere, thus never surprised when it didn't, nor
thought twice when I had to go some extra effort to make it work.
Not in 1990, certainly. By 1993 or so I think "everyone who was
anyone" offered an ANSI/ISO implementation. Still, though, the amount
of code written post-ANSI was tiny compared to what had been written
in the preceding twenty years.
Like I said, I was no longer using or considering "K&R C" as any kind
of "standard" at least by 1985. Can't remember a single shop that made
it requirement since then either. But that is just me. I obviously
never worked in your shop. (Or likely to have stayed long if I did.
Also, that existing investment in pre-ANSI code couldn't be
ANSIfied easily and mechanically. It wasn't just a matter of adding
prototypes (of which more below), but of sorting out other practices
that had varied across C dialects and that ANSI had standardized.
Replacing `<strings.h>' was fairly simple, replacing `<varargs.h>'
was harder, dealing with whether `unsigned short' promoted to `int'
or to `unsigned int' was harder still, and the litany of glitches
large and small didn't stop there. ANSIfying several million lines
of pre-ANSI code while it was under active development was not a
project for a part-time summer intern!
Doesn't sound like it. Makes me very glad it was never an issue for
me.
As for writing prototype declarations to match K&R-style function
definitions, it's not always possible. The K&R definition expects an
argument that has been subjected to what ANSI calls the "default
argument promotions," and the difficulty is in naming the promoted
type. The implementation gets to make an idiosyncratic decision about
the nature of some types: `enum WhatAmI' is compatible with some kind
of integer, but each implementation gets to make its own decision --
and that decision can influence how a value of that type promotes.
A K&R function with an `enum WhatAmI' parameter may need to be
declared with different prototypes on different systems.
Ha. Never ran into that because I've never considered K&R C anything
to write for or towards. The book was a good guide, but ultimately it
was only a summary of "here is how it should work", after that one had
to address what it was their current compiler actually did.
-ralph