This chapter briefly discusses the scope of the standard and lists some programming practices to avoid and some practices to use.
The ANSI standard on the C programming language is designed to promote the portability of C programs among a variety of data-processing systems. To accomplish this, the standard covers three major areas: the environment in which the program compiles and executes, the semantics and syntax of the language, and the content and semantics of a set of library routines and header files.
Strictly conforming programs adhere to the following guidelines:
They use only those features of the language defined in the standard.
They do not produce output dependent on any ill-defined behavior. Ill-defined behavior includes implementation-defined, undefined, and unspecified behavior which refers to areas that the standard does not specify.
They do not exceed any minimum limit.
This ANSI C environment is designed to be a conforming hosted implementation, which will accept any strictly conforming program. Extensions are allowed only if the behavior of strictly conforming programs is not altered.
In addition to knowing which features of the language and library you can rely on when writing portable programs, you must be able to avoid naming conflicts with support routines used for the implementation of the library. To avoid such naming conflicts, ANSI divides the space of available names into a set reserved for the user and a set reserved for the implementation. Any name is in the user's name space if it meets these three requirements (this rule is given for simplicity; the space of names reserved for the user is actually somewhat larger than this):
It does not begin with an underscore
It is not a keyword in the language
It is not reserved for the ANSI library
Strictly conforming programs may not define any names unless they are in the user's namespace. New keywords as well as those names reserved for the ANSI library are discussed in “Standard Headers” in Chapter 2.
To provide the portable clean environment dictated by ANSI while retaining the many extensions available to SGI users, two modes of compilation are provided for ANSI programs. Each of these switches to the cc command invokes the ANSI compiler:
Enforces a pure ANSI environment, eliminating SGI extensions. The ANSI symbol indicating a pure environment (__STDC__) is defined to be 1 for the preprocessor. Use this mode when compiling strictly conforming programs, because it guarantees purity of the ANSI namespace.
Adds SGI extensions to the environment. This mode is the default. The ANSI preprocessor symbol (__STDC__) is defined to be 1. The symbol to include extensions from standard headers (__EXTENSIONS__) is also defined, as is the symbol to inline certain library routines that are directly supported by the hardware (__INLINE_INTRINSICS.) Note that when these library routines are made to be intrinsic, they may no longer be strictly ANSI conforming (for example, errno may not be set correctly).
Use the switch -fullwarn to receive additional diagnostic warnings that are suppressed by default. SGI recommends using this option with the -woff option to remove selected warnings during software development.
Use the switch -wlint (-o32 mode only) to get lint-like warnings about the compiled source. This option provides lint-like warnings for ANSI and -cckr modes and can be used together with the other cc options and switches.
To compile code using traditional C (that is, non-ANSI), use the switch -cckr. The dialect of C invoked by [-cckr] is referred to interchangeably as -cckr, “the previous version of SGI C,” and “traditional C” in the remainder of this document.
Although the ANSI Standard has added only a few new features to the C language, it has tightened the semantics of many areas. In some cases, constructs were removed that were ambiguous, no longer used, or obvious hacks. The next two sections give two lists of programming practices. The first section recommends practices that you can use to ease your transition to this new environment. The second section lists common C coding practices that cause problems when you use ANSI C.
Follow these recommendations as you code:
Always use function prototypes, and write your function prologues in function prototype form.
Always use casts when converting.
Avoid the following as you code:
Never mix prototyped and nonprototyped declarations of the same function.
Never call a function before it has been declared. This may lead to an incompatible implicit declaration for the function. In particular, this is unlikely to work for prototyped functions that take a variable number of arguments.
Avoid using expressions with side effects as arguments to a function.
Avoid two side effects to the same data location between two successive sequence points (for example, x=++x;).
Avoid declaring functions in a local context, especially if they have prototypes.
Never access parameters that are not specified in the argument list unless using the stdarg facilities. Use the stdarg facilities only on a function with an unbounded argument list (that is, an argument list terminated with ...).
Never cast a pointer type to anything other than another pointer type or an integral type of the same size (unsigned long), and vice versa. Use a union type to access the bit-pattern of a pointer as a nonintegral and nonpointer type (that is, as an array of chars).
Do not hack preprocessor tokens (for example, FOO/**/BAR).
Do not rely on search rules to locate include files that you specify with quotation marks.