0% found this document useful (0 votes)
43 views76 pages

CH 18

Declarations furnish information to the compiler about the meaning of identifiers. Declaration specifiers describe the properties of the variables or functions being declared. Declarers give their names and may provide additional information about their properties.

Uploaded by

BolWol
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
43 views76 pages

CH 18

Declarations furnish information to the compiler about the meaning of identifiers. Declaration specifiers describe the properties of the variables or functions being declared. Declarers give their names and may provide additional information about their properties.

Uploaded by

BolWol
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 76

Chapter 18: Declarations

Copyright 2008 W. W. Norton & Company.


All rights reserved.
1
Chapter 18
Declarations
Chapter 18: Declarations
Declaration Syntax
Declarations furnish information to the compiler about
the meaning of identifiers.
Examples:
i nt i ;
f l oat f ( f l oat ) ;
General form of a declaration:
declaration-specifiers declarators ;
Declaration specifiers describe the properties of the
variables or functions being declared.
Declarators give their names and may provide
additional information about their properties.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
2
Chapter 18: Declarations
Declaration Syntax
Declaration specifiers fall into three categories:
Storage classes
Type qualifiers
Type specifiers
C99 has a fourth category, function specifiers,
which are used only in function declarations.
This category has one member, the keyword i nl i ne.
Type qualifiers and type specifiers should follow
the storage class, but there are no other restrictions
on their order.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
3
Chapter 18: Declarations
Declaration Syntax
There are four storage classes: aut o, st at i c,
ext er n, and r egi st er .
At most one storage class may appear in a
declaration; if present, it should come first.
In C89, there are only two type qualifiers: const
and vol at i l e.
C99 has a third type qualifier, r est r i ct .
A declaration may contain zero or more type
qualifiers.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
4
Chapter 18: Declarations
Declaration Syntax
The keywords voi d, char , shor t , i nt , l ong,
f l oat , doubl e, si gned, and unsi gned are all
type specifiers.
The order in which they are combined doesnt matter.
i nt unsi gned l ong is the same as l ong unsi gned
i nt .
Type specifiers also include specifications of
structures, unions, and enumerations.
Examples: st r uct poi nt { i nt x, y; },
st r uct { i nt x, y; }, st r uct poi nt .
t ypedef names are also type specifiers.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
5
Chapter 18: Declarations
Declaration Syntax
Declarators include:
Identifiers (names of simple variables)
Identifiers followed by [ ] (array names)
Identifiers preceded by * (pointer names)
Identifiers followed by ( ) (function names)
Declarators are separated by commas.
A declarator that represents a variable may be
followed by an initializer.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
6
Chapter 18: Declarations
Declaration Syntax
A declaration with a storage class and three declarators:
A declaration with a type qualifier and initializer but no
storage class:
Copyright 2008 W. W. Norton & Company.
All rights reserved.
7
Chapter 18: Declarations
Declaration Syntax
A declaration with a storage class, a type qualifier, and
three type specifiers:
Function declarations may have a storage class, type
qualifiers, and type specifiers:
Copyright 2008 W. W. Norton & Company.
All rights reserved.
8
Chapter 18: Declarations
Storage Classes
Storage classes can be specified for variables
andto a lesser extentfunctions and
parameters.
Recall that the term block refers to the body of a
function (the part in braces) or a compound
statement, possibly containing declarations.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
9
Chapter 18: Declarations
Properties of Variables
Every variable in a C program has three
properties:
Storage duration
Scope
Linkage
Copyright 2008 W. W. Norton & Company.
All rights reserved.
10
Chapter 18: Declarations
Properties of Variables
The storage duration of a variable determines
when memory is set aside for the variable and
when that memory is released.
Automatic storage duration: Memory for variable is
allocated when the surrounding block is executed and
deallocated when the block terminates.
Static storage duration: Variable stays at the same
storage location as long as the program is running,
allowing it to retain its value indefinitely.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
11
Chapter 18: Declarations
Properties of Variables
The scope of a variable is the portion of the
program text in which the variable can be
referenced.
Block scope: Variable is visible from its point of
declaration to the end of the enclosing block.
File scope: Variable is visible from its point of
declaration to the end of the enclosing file.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
12
Chapter 18: Declarations
Properties of Variables
The linkage of a variable determines the extent to
which it can be shared.
External linkage: Variable may be shared by several
(perhaps all) files in a program.
Internal linkage: Variable is restricted to a single file
but may be shared by the functions in that file.
No linkage: Variable belongs to a single function and
cant be shared at all.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
13
Chapter 18: Declarations
Properties of Variables
The default storage duration, scope, and linkage of
a variable depend on where its declared:
Variables declared inside a block (including a function
body) have automatic storage duration, block scope,
and no linkage.
Variables declared outside any block, at the outermost
level of a program, have static storage duration, file
scope, and external linkage.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
14
Chapter 18: Declarations
Properties of Variables
Example:
We can alter these properties by specifying an explicit
storage class: aut o, st at i c, ext er n, or r egi st er .
Copyright 2008 W. W. Norton & Company.
All rights reserved.
15
Chapter 18: Declarations
The auto Storage Class
The aut o storage class is legal only for variables
that belong to a block.
An aut o variable has automatic storage duration,
block scope, and no linkage.
The aut o storage class is almost never specified
explicitly.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
16
Chapter 18: Declarations
The static Storage Class
The st at i c storage class can be used with all
variables, regardless of where theyre declared.
When used outside a block, st at i c specifies that a
variable has internal linkage.
When used inside a block, st at i c changes the
variables storage duration from automatic to static.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
17
Chapter 18: Declarations
The static Storage Class
Example:
Copyright 2008 W. W. Norton & Company.
All rights reserved.
18
Chapter 18: Declarations
The static Storage Class
When used outside a block, st at i c hides a variable
within a file:
st at i c i nt i ; / * no access t o i i n ot her f i l es */
voi d f 1( voi d)
{
/ * has access t o i */
}
voi d f 2( voi d)
{
/ * has access t o i */
}
This use of st at i c is helpful for implementing
information hiding.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
19
Chapter 18: Declarations
The static Storage Class
A st at i c variable declared within a block
resides at the same storage location throughout
program execution.
A st at i c variable retains its value indefinitely.
Properties of st at i c variables:
A st at i c variable is initialized only once, prior to
program execution.
A st at i c variable declared inside a function is shared
by all calls of the function, including recursive calls.
A function may return a pointer to a st at i c variable.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
20
Chapter 18: Declarations
The static Storage Class
Declaring a local variable to be st at i c allows a
function to retain information between calls.
More often, well use st at i c for reasons of
efficiency:
char di gi t _t o_hex_char ( i nt di gi t )
{
st at i c const char hex_char s[ 16] =
" 0123456789ABCDEF" ;
r et ur n hex_char s[ di gi t ] ;
}
Declaring hex_char s to be st at i c saves time,
because st at i c variables are initialized only once.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
21
Chapter 18: Declarations
The extern Storage Class
The ext er n storage class enables several source
files to share the same variable.
A variable declaration that uses ext er n doesnt
cause memory to be allocated for the variable:
ext er n i nt i ;
In C terminology, this is not a definition of i .
An ext er n declaration tells the compiler that we
need access to a variable thats defined elsewhere.
A variable can have many declarations in a
program but should have only one definition.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
22
Chapter 18: Declarations
The extern Storage Class
Theres one exception to the rule that an ext er n
declaration of a variable isnt a definition.
An ext er n declaration that initializes a variable
serves as a definition of the variable.
For example, the declaration
ext er n i nt i = 0;
is effectively the same as
i nt i = 0;
This rule prevents multiple ext er n declarations
from initializing a variable in different ways.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
23
Chapter 18: Declarations
The extern Storage Class
A variable in an ext er n declaration always has
static storage duration.
If the declaration is inside a block, the variable has
block scope; otherwise, it has file scope:
Copyright 2008 W. W. Norton & Company.
All rights reserved.
24
Chapter 18: Declarations
The extern Storage Class
Determining the linkage of an ext er n variable is
a bit harder.
If the variable was declared st at i c earlier in the file
(outside of any function definition), then it has internal
linkage.
Otherwise (the normal case), the variable has external
linkage.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
25
Chapter 18: Declarations
The register Storage Class
Using the r egi st er storage class in the
declaration of a variable asks the compiler to store
the variable in a register.
A register is a high-speed storage area located in a
computers CPU.
Specifying the storage class of a variable to be
r egi st er is a request, not a command.
The compiler is free to store a r egi st er
variable in memory if it chooses.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
26
Chapter 18: Declarations
The register Storage Class
The r egi st er storage class is legal only for
variables declared in a block.
A r egi st er variable has the same storage
duration, scope, and linkage as an aut o variable.
Since registers dont have addresses, its illegal to
use the &operator to take the address of a
r egi st er variable.
This restriction applies even if the compiler has
elected to store the variable in memory.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
27
Chapter 18: Declarations
The register Storage Class
r egi st er is best used for variables that are
accessed and/or updated frequently.
The loop control variable in a f or statement is a
good candidate for r egi st er treatment:
i nt sum_ar r ay( i nt a[ ] , i nt n)
{
r egi st er i nt i ;
i nt sum= 0;
f or ( i = 0; i < n; i ++)
sum+= a[ i ] ;
r et ur n sum;
}
Copyright 2008 W. W. Norton & Company.
All rights reserved.
28
Chapter 18: Declarations
The register Storage Class
r egi st er isnt as popular as it once was.
Many of todays compilers can determine
automatically which variables would benefit from
being kept in registers.
Still, using r egi st er provides useful
information that can help the compiler optimize
the performance of a program.
In particular, the compiler knows that a
r egi st er variable cant have its address taken,
and therefore cant be modified through a pointer.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
29
Chapter 18: Declarations
The Storage Class of a Function
Function declarations (and definitions) may
include a storage class.
The only options are ext er n and st at i c:
ext er n specifies that the function has external
linkage, allowing it to be called from other files.
st at i c indicates internal linkage, limiting use of the
functions name to the file in which its defined.
If no storage class is specified, the function is
assumed to have external linkage.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
30
Chapter 18: Declarations
The Storage Class of a Function
Examples:
ext er n i nt f ( i nt i ) ;
st at i c i nt g( i nt i ) ;
i nt h( i nt i ) ;
Using ext er n is unnecessary, but st at i c has
benefits:
Easier maintenance. A st at i c function isnt visible
outside the file in which its definition appears, so future
modifications to the function wont affect other files.
Reduced name space pollution. Names of st at i c
functions dont conflict with names used in other files.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
31
Chapter 18: Declarations
The Storage Class of a Function
Function parameters have the same properties as
aut o variables: automatic storage duration, block
scope, and no linkage.
The only storage class that can be specified for
parameters is r egi st er .
Copyright 2008 W. W. Norton & Company.
All rights reserved.
32
Chapter 18: Declarations
Summary
A program fragment that shows all possible ways to
includeor omitstorage classes in declarations of
variables and parameters:
i nt a;
ext er n i nt b;
st at i c i nt c;
voi d f ( i nt d, r egi st er i nt e)
{
aut o i nt g;
i nt h;
st at i c i nt i ;
ext er n i nt j ;
r egi st er i nt k;
}
Copyright 2008 W. W. Norton & Company.
All rights reserved.
33
Chapter 18: Declarations
Summary
Name Storage Duration Scope Linkage
a static file external
b static file
c static file internal
d automatic block none
e automatic block none
g automatic block none
h automatic block none
i static block none
j static block
k automatic block none
In most cases, b and j will be defined in another file and will
have external linkage.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
34
Chapter 18: Declarations
Summary
Of the four storage classes, the most important are
st at i c and ext er n.
aut o has no effect, and modern compilers have
made r egi st er less important.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
35
Chapter 18: Declarations
Type Qualifiers
There are two type qualifiers: const and
vol at i l e.
C99 has a third type qualifier, r est r i ct , which is
used only with pointers.
vol at i l e is discussed in Chapter 20.
const is used to declare read-only objects.
Examples:
const i nt n = 10;
const i nt t ax_br acket s[ ] =
{750, 2250, 3750, 5250, 7000};
Copyright 2008 W. W. Norton & Company.
All rights reserved.
36
Chapter 18: Declarations
Type Qualifiers
Advantages of declaring an object to be const :
Serves as a form of documentation.
Allows the compiler to check that the value of the
object isnt changed.
Alerts the compiler that the object can be stored in
ROM (read-only memory).
Copyright 2008 W. W. Norton & Company.
All rights reserved.
37
Chapter 18: Declarations
Type Qualifiers
It might appear that const serves the same role
as the #def i ne directive, but there are
significant differences between the two features.
#def i ne can be used to create a name for a
numerical, character, or string constant, but
const can create read-only objects of any type.
const objects are subject to the same scope rules
as variables; constants created using #def i ne
arent.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
38
Chapter 18: Declarations
Type Qualifiers
The value of a const object, unlike the value of a
macro, can be viewed in a debugger.
Unlike macros, const objects cant be used in
constant expressions:
const i nt n = 10;
i nt a[ n] ; / *** WRONG ***/
Its legal to apply the address operator (&) to a
const object, since it has an address; a macro
doesnt have an address.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
39
Chapter 18: Declarations
Type Qualifiers
There are no absolute rules that dictate when to
use #def i ne and when to use const .
#def i ne is good for constants that represent
numbers or characters.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
40
Chapter 18: Declarations
Declarators
In the simplest case, a declarator is just an
identifier:
i nt i ;
Declarators may also contain the symbols *, [ ] ,
and ( ) .
A declarator that begins with * represents a
pointer:
i nt *p;
Copyright 2008 W. W. Norton & Company.
All rights reserved.
41
Chapter 18: Declarations
Declarators
A declarator that ends with [ ] represents an array:
i nt a[ 10] ;
The brackets may be left empty if the array is a
parameter, if it has an initializer, or if its storage
class is ext er n:
ext er n i nt a[ ] ;
In the case of a multidimensional array, only the
first set of brackets can be empty.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
42
Chapter 18: Declarations
Declarators
C99 provides two additional options for what goes
between the brackets in the declaration of an array
parameter:
The keyword st at i c, followed by an expression that
specifies the arrays minimum length.
The * symbol, which can be used in a function
prototype to indicate a variable-length array argument.
Chapter 9 discusses both features.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
43
Chapter 18: Declarations
Declarators
A declarator that ends with ( ) represents a
function:
i nt abs( i nt i ) ;
voi d swap( i nt *a, i nt *b) ;
i nt f i nd_l ar gest ( i nt a[ ] , i nt n) ;
C allows parameter names to be omitted in a
function declaration:
i nt abs( i nt ) ;
voi d swap( i nt *, i nt *) ;
i nt f i nd_l ar gest ( i nt [ ] , i nt ) ;
Copyright 2008 W. W. Norton & Company.
All rights reserved.
44
Chapter 18: Declarations
Declarators
The parentheses can even be left empty:
i nt abs( ) ;
voi d swap( ) ;
i nt f i nd_l ar gest ( ) ;
This provides no information about the arguments.
Putting the word voi d between the parentheses is
different: it indicates that there are no arguments.
The empty-parentheses style doesnt let the
compiler check whether function calls have the
right arguments.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
45
Chapter 18: Declarations
Declarators
Declarators in actual programs often combine the
*, [ ] , and ( ) notations.
An array of 10 pointers to integers:
i nt *ap[ 10] ;
A function that has a f l oat argument and returns
a pointer to a f l oat :
f l oat *f p( f l oat ) ;
A pointer to a function with an i nt argument and
a voi d return type:
voi d ( *pf ) ( i nt ) ;
Copyright 2008 W. W. Norton & Company.
All rights reserved.
46
Chapter 18: Declarations
Deciphering Complex Declarations
But what about declarators like the one in the
following declaration?
i nt *( *x[ 10] ) ( voi d) ;
Its not obvious whether x is a pointer, an array, or
a function.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
47
Chapter 18: Declarations
Deciphering Complex Declarations
Rules for understanding declarations:
Always read declarators from the inside out. Locate
the identifier thats being declared, and start
deciphering the declaration from there.
When theres a choice, always favor [] and () over
*. Parentheses can be used to override the normal
priority of [ ] and ( ) over *.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
48
Chapter 18: Declarations
Deciphering Complex Declarations
Example 1:
i nt *ap[ 10] ;
ap is an array of pointers.
Example 2:
f l oat *f p( f l oat ) ;
f p is a function that returns a pointer.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
49
Chapter 18: Declarations
Deciphering Complex Declarations
Example 3:
voi d ( *pf ) ( i nt ) ;
Since *pf is enclosed in parentheses, pf must be
a pointer.
But ( *pf ) is followed by ( i nt ) , so pf must
point to a function with an i nt argument.
The word voi d represents the return type of this
function.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
50
Chapter 18: Declarations
Deciphering Complex Declarations
Understanding a complex declarator often
involves zigzagging from one side of the identifier
to the other:
Copyright 2008 W. W. Norton & Company.
All rights reserved.
51
Chapter 18: Declarations
Deciphering Complex Declarations
A second example of zigzagging:
Copyright 2008 W. W. Norton & Company.
All rights reserved.
52
Chapter 18: Declarations
Deciphering Complex Declarations
Certain things cant be declared in C.
Functions cant return arrays:
i nt f ( i nt ) [ ] ; / *** WRONG ***/
Functions cant return functions:
i nt g( i nt ) ( i nt ) ; / *** WRONG ***/
Arrays of functions arent possible, either:
i nt a[ 10] ( i nt ) ; / *** WRONG ***/
In each case, pointers can be used to get the desired
effect.
For example, a function cant return an array, but it
can return a pointer to an array.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
53
Chapter 18: Declarations
Using Type Definitions to Simplify Declarations
Some programmers use type definitions to help
simplify complex declarations.
Suppose that x is declared as follows:
i nt *( *x[ 10] ) ( voi d) ;
The following type definitions make xs type
easier to understand:
t ypedef i nt *Fcn( voi d) ;
t ypedef Fcn *Fcn_pt r ;
t ypedef Fcn_pt r Fcn_pt r _ar r ay[ 10] ;
Fcn_pt r _ar r ay x;
Copyright 2008 W. W. Norton & Company.
All rights reserved.
54
Chapter 18: Declarations
Initializers
For convenience, C allows us to specify initial
values for variables as were declaring them.
To initialize a variable, we write the =symbol
after its declarator, then follow that with an
initializer.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
55
Chapter 18: Declarations
Initializers
The initializer for a simple variable is an
expression of the same type as the variable:
i nt i = 5 / 2; / * i i s i ni t i al l y 2 */
If the types dont match, C converts the initializer
using the same rules as for assignment:
i nt j = 5. 5; / * conver t ed t o 5 */
The initializer for a pointer variable must be an
expression of the same type or of type voi d *:
i nt *p = &i ;
Copyright 2008 W. W. Norton & Company.
All rights reserved.
56
Chapter 18: Declarations
Initializers
The initializer for an array, structure, or union is
usually a series of values enclosed in braces:
i nt a[ 5] = {1, 2, 3, 4, 5};
In C99, brace-enclosed initializers can have other
forms, thanks to designated initializers.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
57
Chapter 18: Declarations
Initializers
An initializer for a variable with static storage
duration must be constant:
#def i ne FI RST 1
#def i ne LAST 100
st at i c i nt i = LAST - FI RST + 1;
If LAST and FI RST had been variables, the
initializer would be illegal.
Copyright 2008 W. W. Norton & Company.
All rights reserved.
58
Chapter 18: Declarations
Initializers
If a variable has automatic storage duration, its
initializer need not be constant:
i nt f ( i nt n)
{
i nt l ast = n - 1;

}
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

You might also like