Next: , Previous: Using Extensions, Up: Design Advice


3.4 Standard C and Pre-Standard C

1989 Standard C is widespread enough now that it is ok to use its features in new programs. There is one exception: do not ever use the “trigraph” feature of Standard C.

1999 Standard C is not widespread yet, so please do not require its features in programs. It is ok to use its features if they are present.

However, it is easy to support pre-standard compilers in most programs, so if you know how to do that, feel free. If a program you are maintaining has such support, you should try to keep it working.

To support pre-standard C, instead of writing function definitions in standard prototype form,

     int
     foo (int x, int y)
     ...

write the definition in pre-standard style like this,

     int
     foo (x, y)
          int x, y;
     ...

and use a separate declaration to specify the argument prototype:

     int foo (int, int);

You need such a declaration anyway, in a header file, to get the benefit of prototypes in all the files where the function is called. And once you have the declaration, you normally lose nothing by writing the function definition in the pre-standard style.

This technique does not work for integer types narrower than int. If you think of an argument as being of a type narrower than int, declare it as int instead.

There are a few special cases where this technique is hard to use. For example, if a function argument needs to hold the system type dev_t, you run into trouble, because dev_t is shorter than int on some machines; but you cannot use int instead, because dev_t is wider than int on some machines. There is no type you can safely use on all machines in a non-standard definition. The only way to support non-standard C and pass such an argument is to check the width of dev_t using Autoconf and choose the argument type accordingly. This may not be worth the trouble.

In order to support pre-standard compilers that do not recognize prototypes, you may want to use a preprocessor macro like this:

     /* Declare the prototype for a general external function.  */
     #if defined (__STDC__) || defined (WINDOWSNT)
     #define P_(proto) proto
     #else
     #define P_(proto) ()
     #endif