CH 18
CH 18
}
Copyright 2008 W. W. Norton & Company.
All rights reserved.
59
Chapter 18: Declarations
Initializers
A brace-enclosed initializer for an array, structure,
or union must contain only constant expressions:
#def i ne N 2
i nt power s[ 5] =
{1, N, N * N, N * N * N, N * N * N * N};
If Nwere a variable, the initializer would be
illegal.
In C99, this restriction applies only if the variable
has static storage duration.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
60
Chapter 18: Declarations
Initializers
The initializer for an automatic structure or union
can be another structure or union:
voi d g( st r uct par t par t 1)
{
st r uct par t par t 2 = par t 1;
}
The initializer doesnt have to be a variable or
parameter name, although it does need to be an
expression of the proper type.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
61
Chapter 18: Declarations
Uninitialized Variables
The initial value of a variable depends on its
storage duration:
Variables with automatic storage duration have no
default initial value.
Variables with static storage duration have the value
zero by default.
A static variable is correctly initialized based on
its type, not simply set to zero bits.
Its better to provide initializers for static variables
rather than rely on the fact that theyre guaranteed
to be zero.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
62
Chapter 18: Declarations
Inline Functions (C99)
C99 function declarations may contain the
keyword i nl i ne.
i nl i ne is related to the concept of the
overhead of a function callthe work required
to call a function and later return from it.
Although the overhead of a function call slows the
program by only a tiny amount, it may add up in
certain situations.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
63
Chapter 18: Declarations
Inline Functions (C99)
In C89, the only way to avoid the overhead of a
function call is to use a parameterized macro.
C99 offers a better solution to this problem: create
an inline function.
The word inline suggests that the compiler
replaces each call of the function by the machine
instructions for the function.
This technique may cause a minor increase in the
size of the compiled program.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
64
Chapter 18: Declarations
Inline Functions (C99)
Declaring a function to be i nl i ne doesnt
actually force the compiler to inline the
function.
It suggests that the compiler should try to make
calls of the function as fast as possible, but the
compiler is free to ignore the suggestion.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
65
Chapter 18: Declarations
Inline Definitions (C99)
An inline function has the keyword i nl i ne as one of
its declaration specifiers:
i nl i ne doubl e aver age( doubl e a, doubl e b)
{
r et ur n ( a + b) / 2;
}
aver age has external linkage, so other source files
may contain calls of aver age.
However, the definition of aver age isnt an external
definition (its an inline definition instead).
Attempting to call aver age from another file will be
considered an error.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
66
Chapter 18: Declarations
Inline Definitions (C99)
There are two ways to avoid this error.
One option is to add the word st at i c to the
function definition:
st at i c i nl i ne doubl e aver age( doubl e a, doubl e b)
{
r et ur n ( a + b) / 2;
}
aver age now has internal linkage, so it cant be
called from other files.
Other files may contain their own definitions of
aver age, which might be the same or different.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
67
Chapter 18: Declarations
Inline Definitions (C99)
The other option is to provide an external
definition for aver age so that calls are permitted
from other files.
One way to do this is to write the aver age
function a second time (without using i nl i ne)
and put this definition in a different source file.
However, its not a good idea to have two versions
of a function: we cant guarantee that theyll
remain consistent when the program is modified.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
68
Chapter 18: Declarations
Inline Definitions (C99)
A better approach is to put the inline definition of
aver age in a header file:
#i f ndef AVERAGE_H
#def i ne AVERAGE_H
i nl i ne doubl e aver age( doubl e a, doubl e b)
{
r et ur n ( a + b) / 2;
}
#endi f
Lets name this file aver age. h.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
69
Chapter 18: Declarations
Inline Definitions (C99)
Next, well create a matching source file,
aver age. c:
#i ncl ude " aver age. h"
ext er n doubl e aver age( doubl e a, doubl e b) ;
Any file that needs to call the aver age function
can include aver age. h.
The definition of aver age included from
aver age. h will be treated as an external
definition in aver age. c.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
70
Chapter 18: Declarations
Inline Definitions (C99)
A general rule: If all top-level declarations of a
function in a file include i nl i ne but not
ext er n, then the definition of the function in that
file is inline.
If the function is used anywhere in the program,
an external definition of the function will need to
be provided by some other file.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
71
Chapter 18: Declarations
Inline Definitions (C99)
When an inline function is called, the compiler has
a choice:
Perform an ordinary call (using the functions external
definition).
Perform inline expansion (using the functions inline
definition).
Because the choice is left to the compiler, its
crucial that the two definitions be consistent.
The technique just discussed (using the
aver age. h and aver age. c files) guarantees
that the definitions are the same.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
72
Chapter 18: Declarations
Restrictions on Inline Functions (C99)
Restrictions on inline functions with external
linkage:
May not define a modifiable st at i c variable.
May not contain references to variables with internal
linkage.
Such a function is allowed to define a variable that
is both st at i c and const .
However, each inline definition of the function
may create its own copy of the variable.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
73
Chapter 18: Declarations
Using Inline Functions with GCC (C99)
Some compilers, including GCC, supported inline
functions prior to the C99 standard.
Their rules for using inline functions may vary
from the standard.
The scheme described earlier (using the
aver age. h and aver age. c files) may not
work with these compilers.
Version 4.3 of GCC is expected to support inline
functions in the way described in the C99
standard.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
74
Chapter 18: Declarations
Using Inline Functions with GCC (C99)
Functions that are specified to be both st at i c
and i nl i ne should work fine, regardless of the
version of GCC.
This strategy is legal in C99 as well, so its the
safest bet.
A st at i c i nl i ne function can be used within
a single file or placed in a header file and included
into any source file that needs to call the function.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
75
Chapter 18: Declarations
Using Inline Functions with GCC (C99)
A technique for sharing an inline function among
multiple files that works with older versions of
GCC but conflicts with C99:
Put a definition of the function in a header file.
Specify that the function is both ext er n and i nl i ne.
Include the header file into any source file that contains
a call of the function.
Put a second copy of the definitionwithout the words
ext er n and i nl i nein one of the source files.
A final note about GCC: Functions are inlined
only when the - Ocommand-line option is used.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
76