Next: , Previous: , Up: Design Advice   [Contents][Index]


3.4 Standard C and Pre-Standard C

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

The 1999 and 2011 editions of Standard C are not fully supported on all platforms. If you aim to support compilation by compilers other than GCC, you should not require these C features in your programs. It is ok to use these features conditionally when the compiler supports them.

If your program is only meant to compile with GCC, then you can use these features if GCC supports them, when they give substantial benefit.

However, it is easy to support pre-standard compilers in most programs, so if you know how to do that, feel free.

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

Next: , Previous: , Up: Design Advice   [Contents][Index]