1046 lines
43 KiB
HTML
1046 lines
43 KiB
HTML
<HTML><HEAD><TITLE>Declarations</TITLE></HEAD><BODY BGCOLOR="#FFFFFF">
|
|
|
|
<H1><A NAME="Declarations">Declarations</A></H1><HR>
|
|
|
|
<P><B><A HREF="#Declaration Contexts and Levels">Declaration
|
|
Contexts and Levels</A>
|
|
· <A HREF="#Outer Declaration">Outer Declaration</A>
|
|
· <A HREF="#Member Declaration">Member Declaration</A>
|
|
· <A HREF="#Function Definition">Function Definition</A>
|
|
· <A HREF="#Parameter Declaration">Parameter Declaration</A>
|
|
· <A HREF="#Block Declaration">Block Declaration</A>
|
|
· <A HREF="#Prototype Declaration">Prototype Declaration</A>
|
|
· <A HREF="#Type-Name Declaration">Type-Name Declaration</A>
|
|
· <A HREF="#Declaration Levels">Declaration Levels</A>
|
|
· <A HREF="#Visibility and Name Spaces">Visibility
|
|
and Name Spaces</A>
|
|
· <A HREF="#Name Spaces">Name Spaces</A>
|
|
· <A HREF="#Scope">Scope</A>
|
|
· <A HREF="#Linkage and Multiple Declarations">Linkage
|
|
and Multiple Declarations</A>
|
|
· <A HREF="#Linkage">Linkage</A>
|
|
· <A HREF="#Tags">Tags</A>
|
|
· <A HREF="#Type Definition">Type Definition</A>
|
|
· <A HREF="#Object Declaration">Object Declaration</A>
|
|
· <A HREF="#Function Declaration">Function Declaration</A>
|
|
· <A HREF="#Reading Declarations">Reading Declarations</A>
|
|
· <A HREF="#Object Initializers">Object Initializers</A>
|
|
</B></P>
|
|
<HR>
|
|
|
|
<P>A translation unit consists of one or more declarations, each
|
|
of which can:</P>
|
|
|
|
<UL>
|
|
<LI>give meaning to a name that you create for use over some portion
|
|
of a translation unit</LI>
|
|
|
|
<LI>allocate storage for an object and (possibly) define its initial
|
|
contents</LI>
|
|
|
|
<LI>define the behavior of a function</LI>
|
|
|
|
<LI>specify a type</LI>
|
|
</UL>
|
|
|
|
<P>Declarations can contain other declarations in turn.</P>
|
|
|
|
<P>This document describes how to use declarations to construct
|
|
a C program. It describes how to create names and how to use the same
|
|
name for distinct purposes. It also shows how to write object initializers
|
|
to specify the initial values stored in objects. The behavior of
|
|
<A HREF="function.html" tppabs="http://ccs.ucsd.edu/c/function.html">functions</A> is described separately.</P>
|
|
|
|
<H2><A NAME="Declaration Contexts and Levels">Declaration
|
|
Contexts and Levels</A></H2>
|
|
|
|
<P>You can write declarations in different <B>contexts</B>.
|
|
The syntax of an arbitrary declaration (other than a function definition)
|
|
is:</P>
|
|
|
|
<P><IMG SRC="decl.gif" tppabs="http://ccs.ucsd.edu/c/gif/decl.gif"></P>
|
|
|
|
<P>The presentation that follows shows graphically
|
|
how each context restricts the declarations that you can write, by
|
|
eliminating from this syntax diagram those parts that are not permitted
|
|
in a given context. It also describes when you must write
|
|
a name within the declarator part of a declaration and when you must
|
|
not.</P>
|
|
|
|
<P>Here is a sampler of all
|
|
possible declaration contexts:</P>
|
|
|
|
<PRE>
|
|
struct stack { <B><A HREF="#Outer Declaration">outer declaration</A></B>
|
|
int top, a[100]; <B><A HREF="#Member Declaration">member declaration</A></B>
|
|
} stk = {0};
|
|
|
|
void push(val) <B><A HREF="#Function Declaration">function definition</A></B>
|
|
int val; <B><A HREF="#Parameter Declaration">parameter declaration</A></B>
|
|
{
|
|
extern void oflo( <B><A HREF="#Block Declaration">block declaration</A></B>
|
|
char *mesg); <B><A HREF="#Prototype Declaration">prototype declaration</A></B>
|
|
if (stk.top < sizeof a /
|
|
sizeof (int)) <B><A HREF="#Type-Name Declaration">type-name declaration</A></B>
|
|
stk.a[stk.top++] = val;
|
|
else
|
|
oflo("stack overflow");
|
|
}</PRE>
|
|
|
|
<H3> <A NAME="Outer Declaration">Outer Declaration</A></H3>
|
|
|
|
<P>You write an <B>outer declaration</B> as one of the declarations
|
|
that make up a translation unit.
|
|
An outer declaration is one that is not contained within
|
|
another declaration or function definition:</P>
|
|
|
|
<P><IMG SRC="outer_d.gif" tppabs="http://ccs.ucsd.edu/c/gif/outer_d.gif"></P>
|
|
|
|
<P>You can omit the declarator only for a structure, union, or
|
|
enumeration declaration that declares a tag. You must write a name
|
|
within the declarator of any other outer declarator.</P>
|
|
|
|
<H3><A NAME="Member Declaration">Member Declaration</A></H3>
|
|
|
|
<P>You write a <B>member declaration</B> to declare members of
|
|
a structure or union, as part of another declaration.</P>
|
|
|
|
<P><IMG SRC="member_d.gif" tppabs="http://ccs.ucsd.edu/c/gif/member_d.gif"></P>
|
|
|
|
<P>A bitfield can be <B>unnamed</B>. If the declarator
|
|
is for a bitfield that has zero size, do not write a name within the
|
|
declarator. If the declarator is for a bitfield that has nonzero size,
|
|
then you can optionally write a name; otherwise, you <I>must</I> write
|
|
a name.</P>
|
|
|
|
<H3><A NAME="Function Definition">Function Definition</A></H3>
|
|
|
|
<P>You write a <B>function definition</B> as one of the declarations
|
|
that make up a translation unit. You cannot write a function definition
|
|
within another declaration or function definition.</P>
|
|
|
|
<P><IMG SRC="fun_def.gif" tppabs="http://ccs.ucsd.edu/c/gif/fun_def.gif"></P>
|
|
|
|
<P>This is the only context where you can omit both the storage
|
|
class and any type part. You must write a name within the declarator.</P>
|
|
|
|
<H3><A NAME="Parameter Declaration">Parameter Declaration</A></H3>
|
|
|
|
<P>You write a <B>parameter declaration</B> as part of a function
|
|
definition whose function declarator contains a list of parameter
|
|
names. You must write a parameter name within the declarator.</P>
|
|
|
|
<P><IMG SRC="param_d.gif" tppabs="http://ccs.ucsd.edu/c/gif/param_d.gif"></P>
|
|
|
|
<H3><A NAME="Block Declaration">Block Declaration</A></H3>
|
|
|
|
<P>You write a <B>block declaration</B> as one of the declarations
|
|
that begin a block within a function definition.</P>
|
|
|
|
<P><IMG SRC="block_d.gif" tppabs="http://ccs.ucsd.edu/c/gif/block_d.gif"></P>
|
|
|
|
<P>You can omit the declarator only for a structure, union, or
|
|
enumeration declaration that declares a tag. Otherwise, you must write
|
|
a name within the declarator.</P>
|
|
|
|
<H3><A NAME="Prototype Declaration">Prototype Declaration</A></H3>
|
|
|
|
<P>You write a <B>prototype declaration</B> within a declarator
|
|
as part of a function decoration to declare a function parameter.</P>
|
|
|
|
<P><IMG SRC="proto_d.gif" tppabs="http://ccs.ucsd.edu/c/gif/proto_d.gif"></P>
|
|
|
|
<P>If the prototype declaration declares a parameter for a function
|
|
that you are defining (it is part of a function definition), then
|
|
you must write a name within the declarator. Otherwise, you can omit
|
|
the name.</P>
|
|
|
|
<H3><A NAME="Type-Name Declaration">Type-Name Declaration</A></H3>
|
|
|
|
<P>You write a <B>type-name declaration</B> within an expression,
|
|
eihher as a
|
|
<A HREF="express.html#Type Cast" tppabs="http://ccs.ucsd.edu/c/express.html#Type Cast">type cast</A>
|
|
operator or following the
|
|
<A HREF="express.html#sizeof operator" tppabs="http://ccs.ucsd.edu/c/express.html#sizeof operator">sizeof</A> operator. Do
|
|
not write a name within the declarator.</P>
|
|
|
|
<P><IMG SRC="type_d.gif" tppabs="http://ccs.ucsd.edu/c/gif/type_d.gif"></P>
|
|
|
|
<H3><A NAME="Declaration Levels">Declaration Levels</A></H3>
|
|
|
|
<P>You use
|
|
<A HREF="#Member Declaration">member declarations</A> and
|
|
<A HREF="#Type-Name Declaration">type-name declarations</A> only
|
|
to specify type information. You declare the functions and objects
|
|
that make up the program in the remaining five contexts shown above.
|
|
These contexts reside at three <B>declaration levels</B>:</P>
|
|
|
|
<UL>
|
|
<LI><B><A NAME="file-level declaration">File-level declarations</A></B>
|
|
are the <A HREF="#Outer Declaration">outer declarations</A> and
|
|
<A HREF="#Function Definition">function definitions</A>
|
|
that make up the translation unit.</LI>
|
|
|
|
<LI><B><A NAME="parameter-level declaration">Parameter-level
|
|
declarations</A></B> are
|
|
<A HREF="#Parameter Declaration">parameter</A> and
|
|
<A HREF="#Prototype Declaration">prototype declarations</A>
|
|
that declare parameters for functions.</LI>
|
|
|
|
<LI><B><A NAME="block-level declaration">Block-level
|
|
declarations</A></B> are
|
|
<A HREF="#Block Declaration">block declarations</A>.</LI>
|
|
</UL>
|
|
|
|
<P>How the translator interprets a declaration that you write depends
|
|
on the level at which you write it. In particular, the meaning of
|
|
a storage class keyword that you write (or the absence of a storage
|
|
class keyword) differs considerably among the declaration levels.</P>
|
|
|
|
<H2><A NAME="Visibility and Name Spaces">Visibility
|
|
and Name Spaces</A></H2>
|
|
|
|
<P>You use names when you declare or define different entities
|
|
in a program (possibly by including a standard header). The entities
|
|
that have names are:</P>
|
|
|
|
<UL>
|
|
<LI><B><A HREF="preproc.html#macros" tppabs="http://ccs.ucsd.edu/c/preproc.html#macros">macros</A></B> --
|
|
which the translator predefines or which
|
|
the program defines with a
|
|
<A HREF="preproc.html#Define Directives" tppabs="http://ccs.ucsd.edu/c/preproc.html#Define Directives"><I>define</I> directive</A></LI>
|
|
|
|
<LI><B><A HREF="syntax.html#keyword" tppabs="http://ccs.ucsd.edu/c/syntax.html#keyword">keywords</A></B> --
|
|
which the translator predefines</LI>
|
|
|
|
<LI><B><A HREF="#Function Declaration">functions</A></B> and
|
|
<B><A HREF="#Object Declaration">objects</A></B> -- which the program
|
|
declares, and which either the Standard C library or the program defines</LI>
|
|
|
|
<LI><B><A HREF="#Type Definition">type definitions</A></B> and
|
|
<B><A HREF="types.html#enumeration constants" tppabs="http://ccs.ucsd.edu/c/types.html#enumeration constants">enumeration constants</A></B>
|
|
-- which the program defines</LI>
|
|
|
|
<LI><B><A HREF="#Tags">tags</A></B> for enumerations, structures,
|
|
and unions -- which the program declares and can also define</LI>
|
|
|
|
<LI><B><A HREF="function.html#Goto Label" tppabs="http://ccs.ucsd.edu/c/function.html#Goto Label"><I>goto</I> labels</A></B> --
|
|
which the program defines</LI>
|
|
</UL>
|
|
|
|
<P>The program can declare or define some of these entities by including
|
|
<A HREF="lib_over.html#standard headers" tppabs="http://ccs.ucsd.edu/c/lib_over.html#standard headers">standard headers</A>.
|
|
The program can
|
|
<A HREF="function.html#implicit declaration" tppabs="http://ccs.ucsd.edu/c/function.html#implicit declaration">implicitly declare</A>
|
|
a function by calling the function within an expression.</P>
|
|
|
|
<P>Each entity is
|
|
<B><A NAME="visibility">visible</A></B> over some region of the program
|
|
text. You refer to a visible entity by writing its name. A macro,
|
|
for example, is visible from the
|
|
<A HREF="preproc.html#define directive" tppabs="http://ccs.ucsd.edu/c/preproc.html#define directive"><I>define</I> directive</A>
|
|
that defines it to any
|
|
<A HREF="preproc.html#undef directive" tppabs="http://ccs.ucsd.edu/c/preproc.html#undef directive"><I>undef</I> directive</A>
|
|
that removes the definition or to
|
|
the end of the translation unit. An object that you declare within
|
|
a block is visible from where you declare it to the end of the block
|
|
(except where it is masked, as described below).</P>
|
|
|
|
<H3><A NAME="Name Spaces">Name Spaces</A></H3>
|
|
|
|
<P>You can sometimes
|
|
<B><A NAME="masking">mask</A></B> an entity by giving another meaning
|
|
to the same name. An object that you declare within an inner block,
|
|
for example, can mask a declaration in a containing block (until the
|
|
end of the inner block). You can use an existing name for a new entity
|
|
only if its name occupies a different name space from the entity it
|
|
masks. You can specify an open-ended set of name spaces.</P>
|
|
|
|
<P>The following diagram shows
|
|
the relationship between various name spaces:</P>
|
|
|
|
<P><IMG SRC="namesp.gif" tppabs="http://ccs.ucsd.edu/c/gif/namesp.gif"></P>
|
|
|
|
<P>Each box in this diagram is a separate name space.
|
|
You can use a name only
|
|
one way within a given name space. The diagram shows, for example,
|
|
that within a block you cannot use the same name both as a structure
|
|
tag and as a union tag.</P>
|
|
|
|
<PRE>
|
|
union x {int i; float f;};
|
|
struct x {... }; <B>INVALID: same name space</B></PRE>
|
|
|
|
<P>Each box in this diagram masks any boxes to its right. If the
|
|
translator can interpret a name as designating an entity within a
|
|
given box, then the same name in any box to its right is not visible.
|
|
If you define a macro without parameters, for example, then the translator
|
|
will always take the name as the name of the macro. The macro definition
|
|
masks any other meaning.</P>
|
|
|
|
<PRE>
|
|
extern int neg(int x);
|
|
#define neg(x) (-(x))
|
|
y = neg(i + j); <B>macro masks function</B></PRE>
|
|
|
|
<P>You introduce two new name spaces with every block that you
|
|
write. One name space includes all functions, objects, type definitions,
|
|
and enumeration constants that you declare or define within the block.
|
|
The other name space includes all enumeration, structure, and union
|
|
tags that you define within the block. You can also introduce a new
|
|
structure or union tag within a block before you define it by writing
|
|
a declaration without a declarator, as in:</P>
|
|
|
|
<PRE>
|
|
{ <B>new block</B>
|
|
struct x; <B>new meaning for x</B>
|
|
struct y {
|
|
struct x *px; <B>px points to new x</B></PRE>
|
|
|
|
<P>A structure or union declaration with only a tag (and no definition
|
|
or declarator) masks any tag name declared in a containing block.</P>
|
|
|
|
<P>The outermost block of a function definition includes in its
|
|
name space all the parameters for the function, as object declarations.
|
|
The name spaces for a block end with the end of the block.</P>
|
|
|
|
<P>You introduce a new
|
|
<A HREF="function.html#Goto Label" tppabs="http://ccs.ucsd.edu/c/function.html#Goto Label"><I>goto</I> label</A>
|
|
name space with every function definition you write.
|
|
Each <I>goto</I> label name space ends
|
|
with its function definition.</P>
|
|
|
|
<P>You introduce a new member name space with every structure or
|
|
union whose content you define. You identify a member name space by
|
|
the type of left operand that you write for a member selection operator,
|
|
as in <CODE>x.y</CODE> or <CODE>p->y</CODE>.
|
|
A member name space ends with the
|
|
end of the block in which you declare it.</P>
|
|
|
|
<H3><A NAME="Scope">Scope</A></H3>
|
|
|
|
<P>The <B>scope</B> of a name that you declare or define is the
|
|
region of the program over which the name retains its declared or
|
|
defined meaning. A name is
|
|
<A HREF="#visibility">visible</A> over its scope except where it is
|
|
<A HREF="#masking">masked</A>:</P>
|
|
|
|
<UL>
|
|
<LI>A <A HREF="#file-level declaration">file-level declaration</A>
|
|
is in scope from the point where it
|
|
is complete to the end of the translation unit.</LI>
|
|
|
|
<LI>A <A HREF="#parameter-level declaration">parameter-level declaration</A>
|
|
is in scope from the point where
|
|
it is declared in the function definition to the end of the outermost
|
|
block of the function definition. (If there is no function definition,
|
|
the scope of a parameter-level declaration ends with the declaration.)</LI>
|
|
|
|
<LI>A <A HREF="#block-level declaration">block-level declaration</A>
|
|
is in scope from the point where it
|
|
is complete to the end of the block.</LI>
|
|
</UL>
|
|
|
|
<P>A macro name is in scope from the point where it is defined (by a
|
|
<A HREF="preproc.html#define directive" tppabs="http://ccs.ucsd.edu/c/preproc.html#define directive"><I>define</I> directive</A>)
|
|
to the point where its definition is removed (by an
|
|
<A HREF="preproc.html#undef directive" tppabs="http://ccs.ucsd.edu/c/preproc.html#undef directive"><I>undef</I> directive</A>, if any).
|
|
You cannot mask a macro name.</P>
|
|
|
|
<H2><A NAME="Linkage and Multiple Declarations">Linkage
|
|
and Multiple Declarations</A></H2>
|
|
|
|
<P>You can sometimes use the same name to refer to the same entity
|
|
in multiple declarations. For functions and objects, you write declarations
|
|
that specify various kinds of
|
|
<A HREF="#Linkage">linkage</A> for the name you declare.
|
|
By using linkage, you can write multiple declarations:</P>
|
|
|
|
<UL>
|
|
<LI>for the same name in the same name space</LI>
|
|
|
|
<LI>for the same name in different name spaces</LI>
|
|
</UL>
|
|
|
|
<P>In either of these two cases, you can have the declarations
|
|
refer to the same function or object.</P>
|
|
|
|
<P>You can use the same enumeration, structure, or union tag in
|
|
multiple declarations to refer to a common type. Similarly, you can
|
|
use a type definition to define an arbitrary type in one declaration
|
|
and use that type in other declarations.</P>
|
|
|
|
<H3><A NAME="Linkage">Linkage</A></H3>
|
|
|
|
<P>A declaration specifies the <B>linkage</B> of a name. Linkage
|
|
determines whether the same name declared in different declarations
|
|
refers to the same function or object. There are three kinds of linkage:</P>
|
|
|
|
<UL>
|
|
<LI>A name with
|
|
<B><A NAME="external linkage">external linkage</A></B>
|
|
designates the same function
|
|
or object as does any other declaration for the same name with external
|
|
linkage. The two declarations can be in the same translation unit
|
|
or in different translation units. Different names that you write
|
|
with external linkage must differ (other than in case) within the
|
|
first six characters.</LI>
|
|
|
|
<LI>A name with
|
|
<B><A NAME="internal linkage">internal linkage</A></B>
|
|
designates the same function
|
|
or object as does any other declaration for the same name with internal
|
|
linkage in the same translation unit.</LI>
|
|
|
|
<LI>A name with
|
|
<B><A NAME="no linkage">no linkage</A></B>
|
|
designates a unique object or a type definition;
|
|
do not declare the same name again in the same name space.</LI>
|
|
</UL>
|
|
|
|
<P>The names of functions always have either external or internal
|
|
linkage.</P>
|
|
|
|
<P>There are separate rules for determining linkage of
|
|
<A HREF="#Object Declaration">objects</A> and
|
|
<A HREF="#Function Declaration">functions</A>.
|
|
In either case, however, do not declare
|
|
the same name with both internal linkage and external linkage in the
|
|
same translation unit.</P>
|
|
|
|
<P>Whenever two declarations designate the same function or object,
|
|
the types specified in the two declarations must be compatible. If
|
|
two such declarations are in the same name space, the resulting type
|
|
for the second declaration is the
|
|
<A HREF="types.html#Compatible and Composite Types" tppabs="http://ccs.ucsd.edu/c/types.html#Compatible and Composite Types">composite type</A>.</P>
|
|
|
|
<P>For example, a valid combination of declarations is:</P>
|
|
|
|
<PRE>
|
|
extern int a[]; <B>external linkage</B>
|
|
extern int a[10]; <B>type is compatible</B></PRE>
|
|
|
|
<H3><A NAME="Tags">Tags</A></H3>
|
|
|
|
<P>You use enumeration, structure, and union <B>tags</B> to designate
|
|
the same integer, structure, or union type in multiple declarations.
|
|
You provide a definition for the type (enclosed in braces) in no more
|
|
than one of the declarations. You can use a structure or union tag
|
|
(but not an enumeration tag) in a declaration before you define the
|
|
type, to designate an
|
|
<A HREF="types.html#incomplete structure types" tppabs="http://ccs.ucsd.edu/c/types.html#incomplete structure types">incomplete structure</A> or
|
|
<A HREF="types.html#incomplete union types" tppabs="http://ccs.ucsd.edu/c/types.html#incomplete union types">incomplete union</A> type.
|
|
When you later provide a definition
|
|
for the incomplete structure or union type, it must be in the same
|
|
<A HREF="#Name Spaces">name space</A>.</P>
|
|
|
|
<P>For example:</P>
|
|
|
|
<PRE>
|
|
struct node { <B>begin definition of node</B>
|
|
int type, value;
|
|
struct node *L, *R; <B>valid: although node incomplete</B>
|
|
} *root = NULL; <B>node now complete</B></PRE>
|
|
|
|
<P>Here, a declaration that refers to the structure whose tag is
|
|
<CODE>node</CODE> appears before the structure type is complete. This is
|
|
the only way to declare a structure that refers to itself
|
|
in its definition.</P>
|
|
|
|
<H3><A NAME="Type Definition">Type Definition</A></H3>
|
|
|
|
<P>You use type definitions to designate the same arbitrary type
|
|
in multiple declarations. A type definition is not a new type; it
|
|
is a synonym for the type you specify when you write the type definition.</P>
|
|
|
|
<P>For example:</P>
|
|
|
|
<PRE>
|
|
typedef int I, AI[], *PI;
|
|
extern int i, ai[10], *pi;
|
|
extern I i; <B>valid: compatible type</B>
|
|
extern AI ai; <B>valid: compatible type</B>
|
|
extern PI pi; <B>valid: compatible type</B></PRE>
|
|
|
|
<P>You can write any type in a type definition. You cannot, however,
|
|
use a type definition in a function definition if the parameter list
|
|
for the function being defined is specified by the type definition.</P>
|
|
|
|
<P>For example:</P>
|
|
|
|
<PRE>
|
|
typedef void VOID; <B>valid type definition</B>
|
|
typedef VOID VF(int x); <B>valid type definition</B>
|
|
VF *pf; <B>valid use of type definition</B>
|
|
VF f { <B>INVALID use of type definition</B></PRE>
|
|
|
|
<P>The parameter list for a function must appear explicitly as
|
|
a function decoration in the declarator part of a function definition,
|
|
as in:</P>
|
|
|
|
<PRE>
|
|
VOID f(int x) { <B>valid use of type definition</B></PRE>
|
|
|
|
<P>A type definition behaves exactly like its synonym when the
|
|
translator compares types. (The type definition and its synonym are
|
|
<A HREF="types.html#Compatible and Composite Types" tppabs="http://ccs.ucsd.edu/c/types.html#Compatible and Composite Types">compatible</A>.)</P>
|
|
|
|
<H2><A NAME="Object Declaration">Object Declaration</A></H2>
|
|
|
|
<P>You declare the objects that the program manipulates at
|
|
<A HREF="#file-level declaration">file level</A>, at
|
|
<A HREF="#parameter-level declaration">parameter level</A>
|
|
(within a function definition), or at
|
|
<A HREF="#block-level declaration">block level</A>.
|
|
The storage class keyword you write (if any) determines
|
|
several properties of an object declaration. The same storage class
|
|
can have different meanings at the three declaration levels.</P>
|
|
|
|
<P>The properties you specify by writing a given storage class
|
|
at a given declaration level are
|
|
<A HREF="#Linkage">linkage</A>,
|
|
<A HREF="#storage duration">storage duration</A>,
|
|
<A HREF="#forms of initialization">form of initialization</A>, and
|
|
<A HREF="#object definition status">object definition status</A>.
|
|
An object declaration can specify that a name has:</P>
|
|
|
|
<UL>
|
|
<LI><A HREF="#external linkage">external linkage</A></LI>
|
|
|
|
<LI><A HREF="#internal linkage">internal linkage</A></LI>
|
|
|
|
<LI><A HREF="#no linkage">no linkage</A></LI>
|
|
</UL>
|
|
|
|
<P>Some declarations accept the
|
|
<B><A NAME="previous linkage">previous linkage</A></B> of a declaration
|
|
that is visible at file level for the same name (with external or
|
|
internal linkage). If such a declaration is not visible, then the
|
|
previous linkage is taken to be external linkage.</P>
|
|
|
|
<P>An object declaration can specify that the declared object has
|
|
one of two <B><A NAME="storage duration">storage durations</A></B>:</P>
|
|
|
|
<UL>
|
|
<LI>An object with
|
|
<B><A NAME="static duration">static duration</A></B> exists from
|
|
<A HREF="lib_over.html#program startup" tppabs="http://ccs.ucsd.edu/c/lib_over.html#program startup">program startup</A> to
|
|
<A HREF="lib_over.html#program termination" tppabs="http://ccs.ucsd.edu/c/lib_over.html#program termination">program termination</A>.
|
|
It assumes its initial value prior to program startup.</LI>
|
|
|
|
<LI>An object with
|
|
<B><A NAME="dynamic duration">dynamic duration</A></B> exists from
|
|
the time that control enters the block
|
|
in which you declare the object to the
|
|
time that control leaves the block. If you specify an initializer,
|
|
then the initializer is evaluated and its value is stored in the object
|
|
when control enters the block. (A
|
|
<A HREF="function.html#Goto Statement" tppabs="http://ccs.ucsd.edu/c/function.html#Goto Statement"><I>goto</I></A> or
|
|
<A HREF="function.html#Switch Statement" tppabs="http://ccs.ucsd.edu/c/function.html#Switch Statement"><I>switch</I> statement</A>
|
|
that transfers control to a
|
|
<A HREF="function.html#Case Label" tppabs="http://ccs.ucsd.edu/c/function.html#Case Label"><I>case</I></A>,
|
|
<A HREF="function.html#Default Label" tppabs="http://ccs.ucsd.edu/c/function.html#Default Label"><I>default</I></A>, or
|
|
<A HREF="function.html#Goto Label" tppabs="http://ccs.ucsd.edu/c/function.html#Goto Label"><I>goto</I> label</A>
|
|
within the block allocates storage for objects with dynamic
|
|
duration but it does not store any initial values.) A function that
|
|
calls itself recursively, either directly or indirectly, allocates
|
|
a separate version of an object with dynamic duration for each activation
|
|
of the block that declares the object.</LI>
|
|
</UL>
|
|
|
|
<P>A type definition for an object type has
|
|
<B><A NAME="no duration">no duration</A></B>
|
|
because duration has no meaning in this case.</P>
|
|
|
|
<P>An object declaration can permit one of two
|
|
<B><A NAME="forms of initialization">forms of initialization</A></B>:</P>
|
|
|
|
<UL>
|
|
<LI>A
|
|
<B><A NAME="static initializer">static initializer</A></B>
|
|
contains only expressions that the translator can
|
|
<A HREF="express.html#Classes of Expressions" tppabs="http://ccs.ucsd.edu/c/express.html#Classes of Expressions">evaluate</A>
|
|
prior to program startup.</LI>
|
|
|
|
<LI>A
|
|
<B><A NAME="dynamic initializer">dynamic initializer</A></B>
|
|
can contain an expression that
|
|
the program evaluates when it executes, called an
|
|
<A HREF="express.html#rvalue expression" tppabs="http://ccs.ucsd.edu/c/express.html#rvalue expression">rvalue expression</A>.
|
|
If you write a list of expressions
|
|
(separated by commas and enclosed in braces) to
|
|
<A HREF="#Object Initializers">initialize an object</A>
|
|
of array, structure, or union type,
|
|
then each expression must be a valid static initializer, even within
|
|
a dynamic initializer.</LI>
|
|
</UL>
|
|
|
|
<P>You must write
|
|
<B><A NAME="no initializer">no initializer</A></B> in some cases.</P>
|
|
|
|
<P>Each of the four kinds of
|
|
<B><A NAME="object definition status">object definition status</A></B>
|
|
of a declaration
|
|
determines whether the declaration causes storage for an object to
|
|
be allocated:</P>
|
|
|
|
<UL>
|
|
<LI>If an object declaration is an
|
|
<B><A NAME="object definition">object definition</A></B>, then it causes
|
|
storage to be allocated for the object.</LI>
|
|
|
|
<LI>If an object declaration is a
|
|
<B><A NAME="tentative declaration">tentative definition</A></B> and
|
|
you write no definition for the same object later in the translation
|
|
unit, then the translator allocates storage for the object at the
|
|
end of the translation unit. The initial value in this case is all
|
|
zeros.</LI>
|
|
|
|
<LI>If an object declaration is a
|
|
<B><A HREF="#Type Definition">type definition</A></B>, then it
|
|
only defines a type. (No object exists.)</LI>
|
|
|
|
<LI>If an object declaration is <B>not a definition</B> and you
|
|
do not write an initializer, then the declaration does not allocate
|
|
storage for the object. If you write any expression that refers to
|
|
the object, then you must provide a definition (in the same or another
|
|
translation unit) that designates the same object.</LI>
|
|
</UL>
|
|
|
|
<P>The following table summarizes the effect
|
|
of each storage class at each declaration level on object declarations:</P>
|
|
|
|
<PRE>
|
|
<B>Storage File-Level Parameter-Level Block-Level
|
|
Class Declaration Declaration Declaration</B>
|
|
|
|
<B>none</B> external linkage no linkage no linkage
|
|
static duration dynamic duration dynamic duration
|
|
static initializer no initializer dynamic initializer
|
|
tentative definition definition definition
|
|
|
|
auto -- -- no linkage
|
|
dynamic duration
|
|
dynamic initializer
|
|
definition
|
|
|
|
extern previous linkage -- previous linkage
|
|
static duration static duration
|
|
static initializer no initializer
|
|
not a definition not a definition
|
|
|
|
register -- no linkage no linkage
|
|
dynamic duration dynamic duration
|
|
no initializer dynamic initializer
|
|
definition definition
|
|
|
|
static internal linkage -- no linkage
|
|
static duration static duration
|
|
static initializer static initializer
|
|
tentative definition definition
|
|
|
|
typedef no linkage -- no linkage
|
|
no duration no duration
|
|
no initializer no initializer
|
|
type definition type definition</PRE>
|
|
|
|
<P>The table specifies the definition status assuming that you do not
|
|
write an initializer. In all cases, if you write an initializer (where
|
|
permitted), then the declaration allocates storage for the object.
|
|
(It is a definition.) For example, the following two declarations
|
|
both name the same object:</P>
|
|
|
|
<PRE>
|
|
static int abc; <B>internal linkage, tentative definition</B>
|
|
extern int abc; <B>previous linkage, no definition</B></PRE>
|
|
|
|
<H2><A NAME="Function Declaration">Function Declaration</A></H2>
|
|
|
|
<P>You declare the functions that a program calls at
|
|
<A HREF="#file-level declaration">file level</A> or at
|
|
<A HREF="#block-level declaration">block level</A>.
|
|
The translator alters any declaration you write
|
|
at parameter level with type <I>function returning T</I> to type <I>pointer
|
|
to function returning T,</I> which is an object type.</P>
|
|
|
|
<P>The properties you specify by writing a given storage class
|
|
at a given declaration level are
|
|
<A HREF="#Linkage">linkage</A> and
|
|
<A HREF="#function definition status">function definition status</A>.
|
|
A function declaration can specify that a name has:</P>
|
|
|
|
<UL>
|
|
<LI><A HREF="#internal linkage">internal linkage</A></LI>
|
|
|
|
<LI><A HREF="#no linkage">no linkage</A></LI>
|
|
</UL>
|
|
|
|
<P>Some declarations accept the
|
|
<A HREF="#previous linkage">previous linkage</A> of a declaration
|
|
that is visible at file level for the same name (with external or
|
|
internal linkage). If such a declaration is not visible, then the
|
|
previous linkage is taken to be
|
|
<A HREF="#external linkage">external linkage</A></P>
|
|
|
|
<P>The
|
|
<B><A NAME="function definition status">function definition status</A></B>
|
|
of a declaration determines whether
|
|
you can write a function definition in that context. You have one
|
|
of three possibilities:</P>
|
|
|
|
<UL>
|
|
<LI>You <B>can define</B> a function.</LI>
|
|
|
|
<LI>You <B>cannot define</B> a function.</LI>
|
|
|
|
<LI>You provide a
|
|
<B><A HREF="#Type Definition">type definition</A></B>.
|
|
(No function exists.)</LI>
|
|
</UL>
|
|
|
|
<P>The following table summarizes the effect
|
|
of each storage class, at each declaration level,
|
|
on function declarations:</P>
|
|
|
|
<PRE>
|
|
<B>Storage File-Level Parameter-Level Block-Level
|
|
Class Declaration Declaration Declaration</B>
|
|
|
|
<B>none</B> previous linkage (becomes pointer previous linkage
|
|
can define to function) cannot define
|
|
|
|
auto -- -- --
|
|
|
|
extern previous linkage -- previous linkage
|
|
can define cannot define
|
|
|
|
register -- (becomes pointer --
|
|
to function)
|
|
|
|
static internal linkage -- --
|
|
can define
|
|
|
|
typedef no linkage -- no linkage
|
|
type definition type definition</PRE>
|
|
|
|
<P>For example, the following declarations both name the same function:</P>
|
|
|
|
<PRE>
|
|
static int f(void); <B>internal linkage</B>
|
|
extern int f(void); <B>previous linkage</B></PRE>
|
|
|
|
<H2><A NAME="Reading Declarations">Reading Declarations</A></H2>
|
|
|
|
<P>Reading a declaration is not always easy. Proceed with caution
|
|
any time:</P>
|
|
|
|
<UL>
|
|
<LI>you omit the name</LI>
|
|
|
|
<LI>you write parentheses in the declarator</LI>
|
|
|
|
<LI>you give a new meaning to a name that is visible
|
|
as a type definition</LI>
|
|
</UL>
|
|
|
|
<P>The following provides some simple guidelines for writing and
|
|
reading complex declarations.</P>
|
|
|
|
<P>When you write a declaration, avoid redundant parentheses. In
|
|
particular, never write parentheses around a name,
|
|
as in <CODE>int (x)</CODE>, because it is easy
|
|
for you or others to misread the parenthesized
|
|
name as a parameter list, and the type changes if you omit the name.</P>
|
|
|
|
<P>You <I>must</I> omit the name when you write a
|
|
<A HREF="express.html#Type Cast" tppabs="http://ccs.ucsd.edu/c/express.html#Type Cast"><I>type cast</I> operator</A>.
|
|
You <I>can</I> omit the name in a declarator when you write
|
|
a function parameter declaration that is not part of a function definition.
|
|
If you omit the name in the example above,
|
|
you get <CODE>int ()</CODE>,
|
|
which specifies type <I>function returning int,</I> not type <I>int.</I></P>
|
|
|
|
<P>Avoid writing a declaration that
|
|
<A HREF="#masking">masks</A> a type definition. If
|
|
you must mask a type definition, write at least one type part in the
|
|
masking declaration that is not a type qualifier. The translator assumes
|
|
that a name visible as a type definition is always a type part if
|
|
that is a valid interpretation of the source text, even if another
|
|
interpretation is also valid.</P>
|
|
|
|
<P>For example:</P>
|
|
|
|
<PRE>
|
|
typedef char Small;
|
|
int g(short Small); <B>valid: Small has new meaning</B>
|
|
int f(Small) <B>Small taken as type definition</B>
|
|
short Small; <B>INVALID: not a parameter name</B></PRE>
|
|
|
|
<P>To read a declaration, you must first replace the name if it
|
|
has been omitted. You determine where to write the name by reading
|
|
the declaration from left to right until you encounter:</P>
|
|
|
|
<UL>
|
|
<LI>the end of the declaration</LI>
|
|
|
|
<LI>a right parenthesis</LI>
|
|
|
|
<LI>a left bracket</LI>
|
|
|
|
<LI>a left parenthesis followed by either a type part or a right
|
|
parenthesis</LI>
|
|
</UL>
|
|
|
|
<P>You write the name immediately to the left of this point.</P>
|
|
|
|
<P>For example:</P>
|
|
|
|
<PRE>
|
|
int <B>becomes</B> int x
|
|
void (*)() <B>becomes</B> void (*x)()
|
|
char [] <B>becomes</B> char x[]
|
|
long () <B>becomes</B> long x()</PRE>
|
|
|
|
<P>You read a complex declaration by first locating the name (using
|
|
the previous rules). Then you:</P>
|
|
|
|
<OL>
|
|
<LI>Read the array or function decorations from left to right, beginning
|
|
with the name, until you come to the end of the declarator or to a
|
|
right parenthesis.</LI>
|
|
|
|
<LI>Read the pointer decorations from right to left, beginning back
|
|
at the name, until you come to the beginning of the declarator, to
|
|
a type part, or to a left parenthesis.</LI>
|
|
|
|
<LI>If you encounter a left parenthesis, repeat the first two steps
|
|
(treating the parenthesized declarator as if it were the name).</LI>
|
|
|
|
<LI>Read the type specified by the type parts.</LI>
|
|
</OL>
|
|
|
|
<P>The following diagram can also help:</P>
|
|
|
|
<PRE>
|
|
<B>d7 d6 ( d4 d3 NAME d1 d2 ) d5</B></PRE>
|
|
|
|
<P>Read the decorations in increasing numeric order, beginning
|
|
with <CODE><B>d1</B></CODE> and ending with the type parts
|
|
(<CODE><B>d7</B></CODE>). It is often
|
|
sufficient simply to remember that, in the absence of parentheses
|
|
(or within a pair of grouping parentheses), you read the pointer decorations
|
|
as the last part of the type.</P>
|
|
|
|
<P>For example:</P>
|
|
|
|
<PRE>
|
|
int *fpi(void) <B>is function returning pointer to int</B>
|
|
int (*pfi)(void) <B>is pointer to function returning int</B>
|
|
unsigned int *(* const *name[5][10])(void)
|
|
<B>is array with 5 elements of
|
|
array with 10 elements of
|
|
pointer to
|
|
pointer which is constant to
|
|
function (no parameters) returning
|
|
pointer to
|
|
unsigned int</B></PRE>
|
|
|
|
<H2><A NAME="Object Initializers">Object Initializers</A></H2>
|
|
|
|
<P>You can specify an initial value for an
|
|
<A HREF="#Object Declaration">object</A> by writing an
|
|
<B>initializer</B>. The type of the object
|
|
and the declaration context constrain
|
|
how you write an initializer.</P>
|
|
|
|
<P>You initialize an object with static duration by writing a
|
|
<B><A NAME="static initializer">static initializer</A></B>.
|
|
A static initializer for an object with scalar type
|
|
consists of a single expression (possibly enclosed in braces) that
|
|
the translator can
|
|
<A HREF="express.html#Classes of Expressions" tppabs="http://ccs.ucsd.edu/c/express.html#Classes of Expressions">evaluate</A> prior to
|
|
<A HREF="lib_over.html#program startup" tppabs="http://ccs.ucsd.edu/c/lib_over.html#program startup">program startup</A>.
|
|
A static initializer for an object with array, structure,
|
|
or union type consists of a list
|
|
of one or more initializers separated by commas and enclosed in braces.</P>
|
|
|
|
<P>For example:</P>
|
|
|
|
<PRE>
|
|
extern char *first = NULL;
|
|
static short February[4] = {29, 28, 28, 28};</PRE>
|
|
|
|
<P>You initialize an object with dynamic duration by writing a
|
|
<B><A NAME="dynamic initializer">dynamic initializer</A></B>.
|
|
For other than array types, any
|
|
<A HREF="express.html#rvalue expression" tppabs="http://ccs.ucsd.edu/c/express.html#rvalue expression">rvalue expression</A> that is
|
|
<A HREF="types.html#assignment compatible" tppabs="http://ccs.ucsd.edu/c/types.html#assignment compatible">assignment compatible</A>
|
|
with the type of the object
|
|
can serve as a dynamic initializer. You can also write a dynamic initializer
|
|
in the same form as a static initializer.</P>
|
|
|
|
<P>For example:</P>
|
|
|
|
<PRE>
|
|
auto int bias =
|
|
{RAND_MAX/2}; <B>static form initializer</B>
|
|
auto int val =
|
|
rand() < bias; <B>dynamic form initializer</B></PRE>
|
|
|
|
<P>The initializers that you write within a list separated by commas are
|
|
<B><A NAME="inner initializer">inner initializers</A></B>.
|
|
You write an inner initializer the
|
|
same way you write a static initializer, except that you can omit
|
|
the outermost braces:</P>
|
|
|
|
<UL>
|
|
<LI>For an object of structure type, the list of inner initializers
|
|
you write initializes each member of the structure in turn, beginning
|
|
with the first. The translator skips unnamed bitfields, which you
|
|
cannot initialize.</LI>
|
|
|
|
<LI>For an object of union type, you can initialize only the first
|
|
member of the union.</LI>
|
|
|
|
<LI>For an object of array type, the list of inner initializers
|
|
you write initializes each element of the array in turn, beginning
|
|
with element number zero. The last array subscript varies most rapidly.</LI>
|
|
</UL>
|
|
|
|
<P>Some examples are:</P>
|
|
|
|
<PRE>
|
|
struct complex {
|
|
float real, imag;
|
|
} neg_one = {-1, 0}; <B>values for real and imag</B>
|
|
union {
|
|
struct complex *p;
|
|
float value;
|
|
} val_ptr =
|
|
{&neg_one}; <B>initializes pointer member</B>
|
|
int a23[2][3] =
|
|
{{00, 01, 02}, <B>all braces present</B>
|
|
{10, 11, 12}}; <B>on inner initializers</B>
|
|
int a32[3][2] =
|
|
{00, 01, <B>braces omitted</B>
|
|
10, 11, <B>on inner initializers</B>
|
|
20, 21};</PRE>
|
|
|
|
<P>If you do not provide as many initializers as there are members
|
|
or elements to initialize, the translator initializes any remaining
|
|
members or elements to the value zero. Do not provide excess initializers.
|
|
You can initialize an object of incomplete array type, in which case
|
|
the number of element initializers you write determines the repetition
|
|
count and completes the array type.</P>
|
|
|
|
<P>For example:</P>
|
|
|
|
<PRE>
|
|
double matrix[10][10] =
|
|
{1.0}; <B>rest set to 0</B>
|
|
int ro[] = {1, 5, 10,
|
|
50, 100, 500}; <B>6 elements</B></PRE>
|
|
|
|
<P>You can initialize an array of any character type by writing
|
|
a string literal, or an array of <CODE>wchar_t</CODE>
|
|
by writing a wide character string literal,
|
|
as shorthand for a sequence of character constants.
|
|
The translator retains the terminating null character only when you
|
|
initialize an object of incomplete array type. (An object of complete
|
|
array type is padded as needed with trailing zero initializers.)</P>
|
|
|
|
<P>For example:</P>
|
|
|
|
<PRE>
|
|
char fail[6] = "fail"; <B>same as</B> {'f', 'a', 'i', 'l', 0, 0}
|
|
char bad[] = "bad"; <B>same as</B> {'b', 'a', 'd', '\0'}
|
|
wchar_t hai[3] = L"hai"; <B>same as</B> {L'h', L'a', L'i'}</PRE>
|
|
|
|
<P>But note:</P>
|
|
|
|
<PRE>
|
|
wchar_t hai[3] = {L'h', L'a', L'i',
|
|
'\0'}; <B>INVALID</B></PRE>
|
|
|
|
<P>The following table summarizes the various
|
|
constraints on initializer expressions or initializer lists, depending
|
|
on context and the type of the object:</P>
|
|
|
|
<PRE>
|
|
<B> Dynamic Static Inner
|
|
Type Initializer Initializer Initializer</B>
|
|
|
|
arithmetic { arithmetic { arithmetic { arithmetic
|
|
rvalue } constant constant
|
|
expression } expression }
|
|
|
|
arithmetic arithmetic arithmetic
|
|
rvalue constant constant
|
|
expression expression
|
|
|
|
pointer { assignment- { address { address
|
|
compatible constant constant
|
|
rvalue } expression } expression }
|
|
|
|
assignment- address address
|
|
compatible constant constant
|
|
rvalue expression expression
|
|
|
|
structure { inner { inner { inner
|
|
initializer list initializer list initializer list
|
|
for members } for members } for members }
|
|
|
|
compatible inner
|
|
structure initializer list
|
|
rvalue for members
|
|
|
|
union { inner { inner { inner
|
|
initializer list initializer list initializer list
|
|
for first for first for first
|
|
member } member } member }
|
|
|
|
compatible inner
|
|
union initializer list
|
|
rvalue for first
|
|
member
|
|
|
|
array { inner { inner { inner
|
|
initializer list initializer list initializer list
|
|
for elements } for elements } for elements }
|
|
|
|
inner
|
|
initializer list
|
|
for elements
|
|
|
|
array of { "..." } { "..." } { "..." }
|
|
character "..." "..." "..."
|
|
|
|
array of { L"..." } { L"..." } { L"..." }
|
|
wchar_t L"..." L"..." L".."</PRE>
|
|
|
|
<P>This table shows you, for example,
|
|
that you can write an arbitrary arithmetic
|
|
<A HREF="express.html#rvalue expression" tppabs="http://ccs.ucsd.edu/c/express.html#rvalue expression">rvalue expression</A> as the
|
|
initializer for an object with arithmetic type and dynamic duration.
|
|
You can write an
|
|
<A HREF="express.html#arithmetic constant expression" tppabs="http://ccs.ucsd.edu/c/express.html#arithmetic constant expression">arithmetic
|
|
constant expression</A>, with or without braces,
|
|
anywhere you initialize an object with arithmetic type.</P>
|
|
|
|
<P>The table also shows you that you can initialize the elements
|
|
of an object of array type, in any context, by writing a list of initializers
|
|
in braces. You can omit the braces only for a string literal initializer
|
|
or for a list you write as an inner initializer for some containing
|
|
initializer.</P>
|
|
|
|
<HR>
|
|
<P>See also the
|
|
<B><A HREF="index.html#Table of Contents" tppabs="http://ccs.ucsd.edu/c/index.html#Table of Contents">Table of Contents</A></B> and the
|
|
<B><A HREF="_index.html" tppabs="http://ccs.ucsd.edu/c/_index.html">Index</A></B>.</P>
|
|
|
|
<P><I>
|
|
<A HREF="crit_pb.html" tppabs="http://ccs.ucsd.edu/c/crit_pb.html">Copyright</A> © 1989-1996
|
|
by P.J. Plauger and Jim Brodie. All rights reserved.</I></P>
|
|
|
|
</BODY></HTML>
|