The most important difference between the original 'K&R' C, and ANSI/ISO C89/90, was function prototypes. These started being supported by some compilers in the mid-eighties, were formally available with the ratification of the standard in 1989-90.

But cross-platform code – say heavily cross-platform code, something that needed to compile on a lot of different platforms, including ones where GCC wasn't necessarily available yet and you had to use vendor compilers of very patchy quality – couldn't necessarily assume availability of the latest features.

Roughly how long was it before cross-platform code – something like Emacs, Oracle, Nethack – started at least assuming you could use function prototypes?


Kevin Sherlock, good idea about the old tarballs. DrSheldon, thanks for the reply on NetHack! Checking Emacs 21.4, dating from 2005, it is still using K&R function definitions. I'm not clear whether the status of that is 'yes these are still required for compatibility' or 'no longer required, changing them to modern function prototypes is still on the to-do list' but still a useful data point.

On the other hand, checking Postgres 95, the earliest version of that project for which I can find sources, it is using modern function prototypes.

  • 4
    As I remember, NetHack was probably the last holdout. It wasn’t until very recently until the DevTeam started allowing ANSI C features. Feb 27, 2021 at 20:16
  • 2
    Otherwise though, I think the criteria specified here are too nebulous for this question to be objectively answerable. Feb 27, 2021 at 20:20
  • 2
    Seems like if you went through the old Emacs or Netback source code tarballs you could find an answer. Feb 27, 2021 at 20:29
  • I’m voting to close this question because low effort Feb 27, 2021 at 20:30
  • 1
    It seems unanswerable in general; each program is surely different. I know I for one started using ANSI C as soon as the two systems I cared about had reasonably-conformant compliers, probably in the late 80s/ Feb 28, 2021 at 3:59

1 Answer 1


The NetHack sources have several macros which are conditional on whether KR1ED is defined, which stands for Kernighan and Ritchie's book The C Programming Language first edition. If one's compiler is pre-ANSI, you must #define KR1ED; if your compiler is ANSI-compliant, you leave KR1ED undefined. Thus, the change in how functions are prototyped occurred between K&R first edition and ANSI C. Specifically for NetHack, I believe this was around version 3.0, as that is when there was rapid spread to other platforms.

Function prototypes in NetHack are wrapped in one of several macros, the implementation of which depends on the existence of KR1ED:

  • NDECL wraps prototypes that return void.
  • FDECL wraps most function prototypes.
  • VDECL wraps prototypes of functions with variable parameters.

The current version of NetHack still uses these prototype wrappers. However, it is scheduled to be taken out in the next version.

Not the answer you're looking for? Browse other questions tagged or ask your own question.