Using Standard C Headers · C Library Conventions · · Program Startup and Termination
All Standard C library entities are declared or defined in one or more
standard headers.
To make use of a library entity in a program, write an
include directive
that names the relevant
standard header.
The full set of 18 Standard C headers constitutes a
hosted implementation:
<assert.h>
,
<ctype.h>
,
<errno.h>
,
<float.h>
,
<iso646.h>
,
<limits.h>
,
<locale.h>
,
<math.h>
,
<setjmp.h>
,
<signal.h>
,
<stdarg.h>
,
<stddef.h>
,
<stdio.h>
,
<stdlib.h>
,
<string.h>
,
<time.h>
,
<wchar.h>
, and
<wctype.h>
.
(The headers
<iso646.h>
,
<wchar.h>
, and
<wctype.h>
are added with
Amendment 1, an addition
to the C Standard published in 1995.)
A freestanding implementation
of Standard C provides only a subset of these standard headers:
<float.h>
,
<limits.h>
,
<stdarg.h>
, and
<stddef.h>
.
Each freestanding implementation defines:
You include the contents of a standard header by naming it in an include directive, as in:
#include <stdio.h> /* include I/O facilities */
You can include the standard headers in any order, a standard header more than once, or two or more standard headers that define the same macro or the same type. Do not include a standard header within a declaration. Do not define macros that have the same names as keywords before you include a standard header.
A standard header never includes another standard header. A standard header declares or defines only the entities described for it in this document.
Every function in the library is declared in a standard header. The standard header can also provide a masking macro, with the same name as the function, that masks the function declaration and achieves the same effect. The macro typically expands to an expression that executes faster than a call to the function of the same name. The macro can, however, cause confusion when you are tracing or debugging the program. So you can use a standard header in two ways to declare or define a library function. To take advantage of any macro version, include the standard header so that each apparent call to the function can be replaced by a macro expansion.
For example:
#include <ctype.h> char *skip_space(char *p) { while (isspace(*p)) can be a macro ++p; return (p); }
To ensure that the program calls the actual library function, include the standard header and remove any macro definition with an undef directive.
For example:
#include <ctype.h> #undef isspace remove any macro definition int f(char *p) { while (isspace(*p)) must be a function ++p;
You can use many functions in the library without including a standard header (although this practice is not recommended). If you do not need defined macros or types to declare and call the function, you can simply declare the function as it appears in this chapter. Again, you have two choices. You can declare the function explicitly.
For example:
double sin(double x); declared in <math.h> y = rho * sin(theta);
Or you can declare the function implicitly if it is a function returning int with a fixed number of arguments, as in:
n = atoi(str); declared in <stdlib.h>
If the function has a
varying number
of arguments, such as
printf
,
you must declare it explicitly: Either include the standard header
that declares it or write an explicit declaration.
Note also that you cannot define a macro or type definition without including its standard header because each of these varies among implementations.
A library macro that
masks
a function declaration expands to
an expression that evaluates each of its arguments once (and only
once). Arguments that have
side effects
evaluate the same way whether the expression executes
the macro expansion or calls the function.
Macros for the functions
getc
and
putc
are explicit exceptions to this rule. Their stream
arguments can be evaluated more than once. Avoid argument expressions
that have side effects with these macros.
A library function that alters a value stored in memory assumes
that the function accesses no other objects that overlap the
object whose stored value it alters. You cannot depend on consistent
behavior from a library function that accesses and alters the same
storage via different arguments. The function
memmove
is an explicit exception to this rule. Its arguments
can point at objects that overlap.
An implementation has a set of
reserved names that it
can use for its own purposes. All the library names described in this
document are, of course, reserved for the library. Don't define
macros with the same names. Don't try to supply your own definition
of a library function, unless this document explicitly says you can
(only in C++). An unauthorized replacement may be successful on some
implementations and not on others. Names that begin with
two underscores, such as __STDIO
, and names that
begin with an underscore followed by an upper case letter, such as
_Entry
, can be used as macro names, whether or not
a translation unit explicitly includes any standard headers.
Names that begin with an underscore can be defined with external
linkage. Avoid writing such names in a program
that you wish to keep maximally portable.
Some library functions operate on C strings, or pointers to null-terminated strings. You designate a C string that can be altered by an argument expression that has type pointer to char (or type array of char, which converts to pointer to char in an argument expression). You designate a C string that cannot be altered by an argument expression that has type pointer to const char (or type const array of char). In any case, the value of the expression is the address of the first byte in an array object. The first successive element of the array that has a null character stored in it marks the end of the C string.
wchar_t
), followed by a
null wide character.
If an argument to a library function has a pointer type, then the value of the argument expression must be a valid address for an object of its type. This is true even if the library function has no need to access an object by using the pointer argument. An explicit exception is when the description of the library function spells out what happens when you use a null pointer.
Some examples are:
strcpy(s1, 0) is INVALID memcpy(s1, 0, 0) is UNSAFE realloc(0, 50) is the same as malloc(50)
The target environment controls the execution of the program
(in contrast to the translator part of the implementation, which prepares
the parts of the program for execution). The target environment passes
control to the program at
program startup
by calling the function
main
that you define as part of the program.
Program arguments are
C strings
that the target environment provides, such as text from the
command line
that you type to invoke the program. If the program
does not need to access program arguments, you can define main
as:
extern int main(void) { <body of main> }
If the program uses program arguments, you define main
as:
extern int main(int argc, char **argv) { <body of main> }
You can omit either or both of extern int
, since
these are the default storage class and type for a function
definition. For program arguments:
argc
is a value (always greater than zero) that specifies
the number of program arguments.
argv[0]
designates the first element of an array of
C strings.
argv[argc]
designates the last element of the array, whose
stored value is a null pointer.
For example, if you invoke a program by typing:
echo hello
a target environment can call main
with:
argc
.
"echo"
stored
in argv[0]
.
"hello"
stored
in argv[1]
.
argv[2]
.
argv[0]
is the name used to invoke the program. The target
environment can replace this name with a
null string (""
).
The program can alter the values stored in argc
,
in argv
, and in the array objects
whose addresses are stored in argv
.
Before the target environment calls main
, it stores the
initial values you specify in all objects that have static duration.
It also opens three files, controlled by the text-stream objects designated
by the macros:
stdin
--
for standard input
stdout
--
for standard output
stderr
--
for standard error output
If main
returns to its caller, the target environment calls
exit
with the value returned from main
as the status argument to
exit
. If the
return statement that
the program executes has no expression, the status argument is undefined.
This is the case if the program executes the implied
return statement
at the end of the function definition.
You can also call
exit
directly from any expression within the program. In both cases,
exit
calls all functions registered with
atexit
in reverse order of registry and then begins
program termination.
At program termination, the target environment closes
all open files, removes any temporary files that you created by calling
tmpfile
,
and then returns control to the invoker, using the
status argument value to determine the termination status to report
for the program.
The program can terminate abnormally by calling
abort
,
for example. Each implementation defines whether it closes files,
whether it removes temporary files, and what termination status it
reports when a program terminates abnormally.
See also the Table of Contents and the Index.
Copyright © 1989-1996 by P.J. Plauger and Jim Brodie. All rights reserved.