2002-05-19 06:55:13 +00:00
|
|
|
.\" Copyright (C) Caldera International Inc. 2001-2002. All rights reserved.
|
2002-10-12 14:50:50 +00:00
|
|
|
.\"
|
2002-05-19 06:55:13 +00:00
|
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
|
|
.\" modification, are permitted provided that the following conditions are
|
|
|
|
.\" met:
|
2002-10-12 14:50:50 +00:00
|
|
|
.\"
|
2002-05-19 06:55:13 +00:00
|
|
|
.\" Redistributions of source code and documentation must retain the above
|
|
|
|
.\" copyright notice, this list of conditions and the following
|
|
|
|
.\" disclaimer.
|
2002-10-12 14:50:50 +00:00
|
|
|
.\"
|
2002-05-19 06:55:13 +00:00
|
|
|
.\" Redistributions in binary form must reproduce the above copyright
|
|
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
|
|
.\" documentation and/or other materials provided with the distribution.
|
2002-10-12 14:50:50 +00:00
|
|
|
.\"
|
2002-05-19 06:55:13 +00:00
|
|
|
.\" All advertising materials mentioning features or use of this software
|
|
|
|
.\" must display the following acknowledgement:
|
2002-10-12 14:50:50 +00:00
|
|
|
.\"
|
2002-05-19 06:55:13 +00:00
|
|
|
.\" This product includes software developed or owned by Caldera
|
|
|
|
.\" International, Inc. Neither the name of Caldera International, Inc.
|
|
|
|
.\" nor the names of other contributors may be used to endorse or promote
|
|
|
|
.\" products derived from this software without specific prior written
|
|
|
|
.\" permission.
|
2002-10-12 14:50:50 +00:00
|
|
|
.\"
|
2002-05-19 06:55:13 +00:00
|
|
|
.\" USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
|
|
|
|
.\" INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
|
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
.\" DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
|
|
|
|
.\" FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
|
|
.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
|
|
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
|
|
.\" OR OTHERWISE) RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
|
|
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
2002-10-12 14:50:50 +00:00
|
|
|
.\"
|
2002-05-19 06:17:52 +00:00
|
|
|
.\" @(#)Clang.ms 8.1 (Berkeley) 6/8/93
|
|
|
|
.\"
|
|
|
|
.\" $FreeBSD$
|
|
|
|
.nr Cl 2
|
|
|
|
.TL
|
|
|
|
The C Programming Language - Reference Manual
|
|
|
|
.AU
|
|
|
|
Dennis M. Ritchie
|
|
|
|
.AI
|
|
|
|
AT&T Bell Laboratories
|
|
|
|
Murray Hill, NJ 07974
|
|
|
|
.PP
|
2002-10-12 14:50:50 +00:00
|
|
|
This manual is a reprint, with updates to the current C standard, from
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIThe C Programming Language\fR,
|
2002-10-12 14:50:50 +00:00
|
|
|
by Brian W. Kernighan and Dennis M. Ritchie, Prentice-Hall, Inc., 1978.
|
2002-05-19 06:55:13 +00:00
|
|
|
.PP
|
|
|
|
\fBThis document is of historical interest only. Do not use it as a reference
|
|
|
|
for modern implementations of C.\fP
|
2002-05-19 06:17:52 +00:00
|
|
|
.EH 'PSD:6-%''The C Programming Language - Reference Manual'
|
|
|
|
.OH 'The C Programming Language - Reference Manual''PSD:6-%'
|
|
|
|
.NH 1
|
|
|
|
Introduction
|
|
|
|
.PP
|
|
|
|
This manual describes the C language on the DEC PDP-11\(dg, the DEC VAX-11,
|
|
|
|
.FS
|
|
|
|
.LP
|
|
|
|
\(dg DEC PDP-11, and DEC VAX-11 are trademarks of Digital Equipment Corporation.
|
|
|
|
.LP
|
|
|
|
\(dd 3B 20 is a trademark of AT&T.
|
|
|
|
.FE
|
|
|
|
and the AT&T 3B 20\(dd.
|
|
|
|
Where differences exist, it concentrates on the VAX, but tries to point
|
2002-10-12 14:50:50 +00:00
|
|
|
out implementation-dependent details. With few exceptions, these dependencies
|
2002-05-19 06:17:52 +00:00
|
|
|
follow directly from the underlying properties of the hardware; the various
|
|
|
|
compilers are generally quite compatible.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
Lexical Conventions
|
|
|
|
.PP
|
2002-10-12 14:50:50 +00:00
|
|
|
There are six classes of tokens\ -\
|
2002-05-19 06:17:52 +00:00
|
|
|
identifiers, keywords, constants, strings, operators, and other separators.
|
|
|
|
Blanks, tabs, new\(hylines,
|
|
|
|
and comments (collectively, ``white space'') as described below
|
|
|
|
are ignored except as they serve to separate
|
|
|
|
tokens.
|
|
|
|
Some white space is required to separate
|
|
|
|
otherwise adjacent identifiers,
|
|
|
|
keywords, and constants.
|
|
|
|
.PP
|
|
|
|
If the input stream has been parsed into tokens
|
|
|
|
up to a given character, the next token is taken
|
|
|
|
to include the longest string of characters
|
|
|
|
which could possibly constitute a token.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Comments
|
|
|
|
.PP
|
|
|
|
The characters
|
|
|
|
.B
|
|
|
|
/*
|
|
|
|
.R
|
|
|
|
introduce a comment which terminates
|
|
|
|
with the characters
|
|
|
|
\fB\(**/\fR.
|
|
|
|
Comments do not nest.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Identifiers (Names)
|
|
|
|
.PP
|
|
|
|
An identifier is a sequence of letters and digits.
|
|
|
|
The first character must be a letter.
|
|
|
|
The underscore
|
|
|
|
(\fB_\fR)
|
|
|
|
counts as a letter.
|
|
|
|
Uppercase and lowercase letters
|
|
|
|
are different.
|
|
|
|
Although there is no limit on the length of a name,
|
|
|
|
only initial characters are significant: at least
|
|
|
|
eight characters of a non-external name, and perhaps
|
|
|
|
fewer for external names.
|
|
|
|
Moreover, some implementations may collapse case
|
|
|
|
distinctions for external names.
|
|
|
|
The external name sizes include:
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
.TS
|
|
|
|
l l.
|
|
|
|
PDP-11 7 characters, 2 cases
|
|
|
|
VAX-11 >100 characters, 2 cases
|
|
|
|
AT&T 3B 20 >100 characters, 2 cases
|
|
|
|
.TE
|
|
|
|
.fi
|
|
|
|
.DE
|
|
|
|
.NH 2
|
|
|
|
Keywords
|
|
|
|
.PP
|
|
|
|
The following identifiers are reserved for use
|
|
|
|
as keywords and may not be used otherwise:
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
.ta 0.8i 1.6i 2.4i 3.2i 4.0i
|
|
|
|
\fBauto do for return typedef
|
|
|
|
break double goto short union
|
|
|
|
case else if sizeof unsigned
|
|
|
|
char enum int static void
|
|
|
|
continue external long struct while
|
|
|
|
default float register switch\fR
|
|
|
|
.ta 0.5i
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
Some implementations also reserve the words
|
|
|
|
.B
|
|
|
|
fortran, asm, gfloat, hfloat
|
|
|
|
.R
|
|
|
|
and
|
|
|
|
.B quad
|
|
|
|
.R
|
|
|
|
.NH 2
|
|
|
|
Constants
|
|
|
|
.PP
|
|
|
|
There are several kinds
|
|
|
|
of constants.
|
|
|
|
Each has a type; an introduction to types is given in ``NAMES.''
|
|
|
|
Hardware characteristics that affect sizes are summarized in
|
|
|
|
``Hardware Characteristics'' under ``LEXICAL CONVENTIONS.''
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 3
|
2002-05-19 06:17:52 +00:00
|
|
|
Integer Constants
|
|
|
|
.br
|
|
|
|
.PP
|
|
|
|
An integer constant consisting of a sequence of digits
|
|
|
|
is taken
|
|
|
|
to be octal if it begins with
|
|
|
|
.B
|
|
|
|
0
|
|
|
|
.R
|
|
|
|
(digit zero).
|
|
|
|
An octal constant consists of the digits \fB0\fR through \fB7\fR only.
|
|
|
|
A sequence of digits preceded by
|
|
|
|
.B
|
|
|
|
0x
|
|
|
|
.R
|
|
|
|
or
|
|
|
|
.B
|
|
|
|
0X
|
|
|
|
.R
|
|
|
|
(digit zero) is taken to be a hexadecimal integer.
|
|
|
|
The hexadecimal digits include
|
|
|
|
.B
|
|
|
|
a
|
|
|
|
.R
|
|
|
|
or
|
|
|
|
.B
|
|
|
|
A
|
|
|
|
.R
|
|
|
|
through
|
|
|
|
.B
|
|
|
|
f
|
|
|
|
.R
|
|
|
|
or
|
|
|
|
.B
|
|
|
|
F
|
|
|
|
.R
|
|
|
|
with values 10 through 15.
|
|
|
|
Otherwise, the integer constant is taken to be decimal.
|
|
|
|
A decimal constant whose value exceeds the largest
|
|
|
|
signed machine integer is taken to be
|
|
|
|
\fBlong\fR;
|
|
|
|
an octal or hex constant which exceeds the largest unsigned machine integer
|
|
|
|
is likewise taken to be
|
|
|
|
.B
|
|
|
|
long\fR.
|
|
|
|
.R
|
|
|
|
Otherwise, integer constants are \fBint\fR.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 3
|
2002-05-19 06:17:52 +00:00
|
|
|
Explicit Long Constants
|
|
|
|
.br
|
|
|
|
.PP
|
|
|
|
A decimal, octal, or hexadecimal integer constant immediately followed
|
|
|
|
by
|
|
|
|
.B
|
|
|
|
l
|
|
|
|
.R
|
|
|
|
(letter ell)
|
|
|
|
or
|
|
|
|
.B
|
|
|
|
L
|
|
|
|
.R
|
|
|
|
is a long constant.
|
|
|
|
As discussed below,
|
|
|
|
on some machines
|
|
|
|
integer and long values may be considered identical.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 3
|
2002-05-19 06:17:52 +00:00
|
|
|
Character Constants
|
|
|
|
.br
|
|
|
|
.PP
|
|
|
|
A character constant is a character enclosed in single quotes,
|
|
|
|
as in '\fBx\fR'.
|
|
|
|
The value of a character constant is the numerical value of the
|
|
|
|
character in the machine's character set.
|
|
|
|
.PP
|
|
|
|
Certain nongraphic characters,
|
|
|
|
the single quote
|
|
|
|
(\fB'\fR)
|
|
|
|
and the backslash
|
|
|
|
(\fB\e\fR),
|
|
|
|
may be represented according to the following table
|
|
|
|
of escape sequences:
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
.TS
|
|
|
|
l l l.
|
|
|
|
new\(hyline NL (LF) \en
|
|
|
|
horizontal tab HT \et
|
|
|
|
vertical tab VT \ev
|
|
|
|
backspace BS \eb
|
|
|
|
carriage return CR \er
|
|
|
|
form feed FF \ef
|
|
|
|
backslash \e \e\e
|
|
|
|
single quote ' \e'
|
|
|
|
bit pattern \fIddd\fR\^ \e\fIddd\fR\^
|
|
|
|
.TE
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
The escape
|
|
|
|
\e\fIddd\fR
|
|
|
|
consists of the backslash followed by 1, 2, or 3 octal digits
|
|
|
|
which are taken to specify the value of the
|
|
|
|
desired character.
|
|
|
|
A special case of this construction is
|
|
|
|
.B
|
|
|
|
\e0
|
|
|
|
.R
|
|
|
|
(not followed
|
|
|
|
by a digit), which indicates the character
|
|
|
|
.B
|
|
|
|
NUL\fR.
|
|
|
|
.R
|
|
|
|
If the character following a backslash is not one
|
|
|
|
of those specified, the
|
|
|
|
behavior is undefined.
|
|
|
|
A new-line character is illegal in a character constant.
|
|
|
|
The type of a character constant is \fBint\fR.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 3
|
2002-05-19 06:17:52 +00:00
|
|
|
Floating Constants
|
|
|
|
.br
|
|
|
|
.PP
|
|
|
|
A floating constant consists of
|
|
|
|
an integer part, a decimal point, a fraction part,
|
|
|
|
an
|
|
|
|
.B
|
|
|
|
e
|
|
|
|
.R
|
|
|
|
or
|
|
|
|
\fBE\fR,
|
|
|
|
and an optionally signed integer exponent.
|
|
|
|
The integer and fraction parts both consist of a sequence
|
|
|
|
of digits.
|
|
|
|
Either the integer part or the fraction
|
|
|
|
part (not both) may be missing.
|
|
|
|
Either the decimal point or
|
|
|
|
the
|
|
|
|
.B
|
|
|
|
e
|
|
|
|
.R
|
|
|
|
and the exponent (not both) may be missing.
|
|
|
|
Every floating constant has type \fBdouble\fR.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 3
|
2002-05-19 06:17:52 +00:00
|
|
|
Enumeration Constants
|
|
|
|
.br
|
|
|
|
.PP
|
|
|
|
Names declared as enumerators
|
|
|
|
(see ``Structure, Union, and Enumeration Declarations'' under
|
|
|
|
``DECLARATIONS'')
|
|
|
|
have type \fBint\fR.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Strings
|
|
|
|
.PP
|
|
|
|
A string is a sequence of characters surrounded by
|
|
|
|
double quotes,
|
|
|
|
as in
|
|
|
|
\fB"..."\fR.
|
|
|
|
A string has type
|
|
|
|
``array of \fBchar\fR'' and storage class
|
|
|
|
\fBstatic\fR
|
|
|
|
(see ``NAMES'')
|
|
|
|
and is initialized with
|
|
|
|
the given characters.
|
|
|
|
The compiler places
|
|
|
|
a null byte
|
|
|
|
(\fB\e0\fR)
|
|
|
|
at the end of each string so that programs
|
|
|
|
which scan the string can
|
|
|
|
find its end.
|
|
|
|
In a string, the double quote character
|
|
|
|
(\fB"\fR)
|
|
|
|
must be preceded by
|
|
|
|
a
|
|
|
|
\fB\e\fR;
|
|
|
|
in addition, the same escapes as described for character
|
|
|
|
constants may be used.
|
|
|
|
.PP
|
|
|
|
A
|
|
|
|
.B
|
|
|
|
\e
|
|
|
|
.R
|
|
|
|
and
|
|
|
|
the immediately following new\(hyline are ignored.
|
|
|
|
All strings, even when written identically, are distinct.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Hardware Characteristics
|
|
|
|
.PP
|
|
|
|
The following figure summarize
|
|
|
|
certain hardware properties that vary from machine to machine.
|
|
|
|
.DS
|
|
|
|
.TS
|
|
|
|
center box;
|
|
|
|
c cfB s cfB s cfB s
|
|
|
|
c c s c s c s
|
|
|
|
l | l1 lp8 | l1 lp8 | l1 lp8.
|
|
|
|
DEC PDP\-11 DEC VAX-11 AT&T 3B
|
|
|
|
(ASCII) (ASCII) (ASCII)
|
|
|
|
.sp
|
|
|
|
_
|
|
|
|
char 8 bits 8 bits 8bits
|
|
|
|
int 16 32 32
|
|
|
|
short 16 16 16
|
|
|
|
long 32 32 32
|
|
|
|
float 32 32 32
|
|
|
|
double 64 64 64
|
|
|
|
float range \(+-10 \(+-38 \(+-10 \(+-38 \(+-10 \(+-38
|
|
|
|
\^ \^ \^ \^
|
|
|
|
double range \(+-10 \(+-38 \(+-10 \(+-38 \(+-10 \(+-308
|
|
|
|
\^ \^ \^ \^
|
|
|
|
.TE
|
2002-05-19 06:55:13 +00:00
|
|
|
.\" .FG 4 4 1 "DEC PDP-11 HARDWARE CHARACTERISTICS"
|
2002-05-19 06:17:52 +00:00
|
|
|
.DE
|
|
|
|
.PP
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
Syntax Notation
|
|
|
|
.PP
|
|
|
|
Syntactic categories are indicated by
|
|
|
|
.I
|
|
|
|
italic
|
|
|
|
.R
|
|
|
|
type
|
|
|
|
and literal words and characters
|
|
|
|
in
|
|
|
|
\fBbold\fR
|
|
|
|
type.
|
|
|
|
Alternative categories are listed on separate lines.
|
|
|
|
An optional terminal or nonterminal symbol is
|
|
|
|
indicated by the subscript ``opt,'' so that
|
|
|
|
.DS
|
|
|
|
{ \fIexpression\v'0.5'\s-2opt\s0\v'-0.5'\fR }
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
indicates an optional expression enclosed in braces.
|
|
|
|
The syntax is summarized in ``SYNTAX SUMMARY''.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
Names
|
|
|
|
.PP
|
|
|
|
The C language bases the interpretation of an
|
|
|
|
identifier upon two attributes of the identifier \(mi its
|
|
|
|
.I
|
|
|
|
storage class
|
|
|
|
.R
|
|
|
|
and its
|
|
|
|
.I
|
|
|
|
type\fR.
|
|
|
|
The storage class determines the location and lifetime
|
|
|
|
of the storage associated with an identifier;
|
|
|
|
the type determines
|
|
|
|
the meaning of the values
|
|
|
|
found in the identifier's storage.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Storage Class
|
|
|
|
.PP
|
2002-05-19 06:55:13 +00:00
|
|
|
.\" The original text had borrowed BL, LI and LE from the mm macros.
|
|
|
|
.\" That way madness lies.
|
2002-05-19 06:17:52 +00:00
|
|
|
There are four declarable storage classes:
|
2002-05-19 06:55:13 +00:00
|
|
|
.RS
|
|
|
|
.br
|
|
|
|
\(bu Automatic
|
|
|
|
.br
|
|
|
|
\(bu Static
|
|
|
|
.br
|
|
|
|
\(bu External
|
|
|
|
.br
|
|
|
|
\(bu Register.
|
|
|
|
.RE
|
2002-05-19 06:17:52 +00:00
|
|
|
.PP
|
|
|
|
Automatic variables are local to each invocation of
|
2002-10-12 14:50:50 +00:00
|
|
|
a block (see ``Compound Statement or Block'' in
|
2002-05-19 06:17:52 +00:00
|
|
|
``STATEMENTS'') and are discarded upon exit from the block.
|
|
|
|
Static variables are local to a block but retain
|
|
|
|
their values upon reentry to a block even after control
|
|
|
|
has left the block.
|
|
|
|
External variables exist and retain their values throughout
|
|
|
|
the execution of the entire program and
|
|
|
|
may be used for communication between
|
|
|
|
functions, even separately compiled functions.
|
|
|
|
Register variables are (if possible) stored in the fast registers
|
|
|
|
of the machine; like automatic
|
|
|
|
variables, they are local to each block and disappear on exit from the block.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Type
|
|
|
|
.PP
|
|
|
|
The C language supports several
|
|
|
|
fundamental
|
|
|
|
types of objects.
|
|
|
|
Objects declared as characters
|
|
|
|
(\fBchar\fR)
|
|
|
|
are large enough to store any member of the implementation's
|
|
|
|
character set.
|
|
|
|
If a genuine character from that character set is
|
|
|
|
stored in a \fBchar\fR variable,
|
|
|
|
its value is equivalent to the integer code for that character.
|
|
|
|
Other quantities may be stored into character variables, but
|
|
|
|
the implementation is machine dependent.
|
|
|
|
In particular, \fBchar\fR may be signed or unsigned by default.
|
|
|
|
.PP
|
|
|
|
Up to three sizes of integer, declared
|
|
|
|
.B
|
|
|
|
short
|
|
|
|
.R
|
|
|
|
\fBint\fR,
|
|
|
|
\fBint\fR,
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
long
|
|
|
|
.R
|
|
|
|
\fBint\fR,
|
|
|
|
are available.
|
|
|
|
Longer integers provide no less storage than shorter ones,
|
|
|
|
but the implementation may make either short integers or long integers,
|
|
|
|
or both, equivalent to plain integers.
|
|
|
|
``Plain'' integers have the natural size suggested
|
|
|
|
by the host machine architecture.
|
|
|
|
The other sizes are provided to meet special needs.
|
|
|
|
.PP
|
|
|
|
The properties of \fBenum\fR types (see ``Structure, Union, and Enumeration Declarations''
|
|
|
|
under ``DECLARATIONS'')
|
|
|
|
are identical to those of
|
|
|
|
some integer types.
|
|
|
|
The implementation may use the range of values to
|
|
|
|
determine how to allocate storage.
|
|
|
|
.PP
|
|
|
|
Unsigned
|
|
|
|
integers, declared
|
|
|
|
.B
|
|
|
|
unsigned,
|
|
|
|
.R
|
|
|
|
obey the laws of arithmetic modulo
|
|
|
|
2\v'-0.5'\fIn\fR\v'0.5'
|
|
|
|
where \fIn\fR is the number of bits in the representation.
|
|
|
|
(On the
|
|
|
|
PDP-11,
|
|
|
|
unsigned long quantities are not supported.)
|
|
|
|
.PP
|
|
|
|
Single-precision floating point
|
|
|
|
(\fBfloat\fR)
|
|
|
|
and double precision floating point
|
|
|
|
(\fBdouble\fR)
|
|
|
|
may be synonymous in some implementations.
|
|
|
|
.PP
|
|
|
|
Because objects of the foregoing types can usefully be interpreted
|
|
|
|
as numbers, they will be referred to as
|
|
|
|
.I
|
|
|
|
arithmetic
|
|
|
|
.R
|
|
|
|
types.
|
|
|
|
\fBChar\fR,
|
|
|
|
.B
|
|
|
|
int
|
|
|
|
.R
|
|
|
|
of all sizes whether \fBunsigned\fR or not, and
|
|
|
|
.B
|
|
|
|
enum
|
|
|
|
.R
|
|
|
|
will collectively be called
|
|
|
|
.I
|
|
|
|
integral
|
|
|
|
.R
|
|
|
|
types.
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
float
|
|
|
|
.R
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
double
|
|
|
|
.R
|
|
|
|
types will collectively be called
|
|
|
|
.I
|
|
|
|
floating
|
|
|
|
.R
|
|
|
|
types.
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
void
|
|
|
|
.R
|
|
|
|
type
|
|
|
|
specifies an empty set of values.
|
|
|
|
It is used as the type returned by functions that
|
|
|
|
generate no value.
|
|
|
|
.PP
|
|
|
|
Besides the fundamental arithmetic types, there is a
|
|
|
|
conceptually infinite class of derived types constructed
|
|
|
|
from the fundamental types in the following ways:
|
2002-05-19 06:55:13 +00:00
|
|
|
.IP \fIArrays\fR
|
2002-05-19 06:17:52 +00:00
|
|
|
of objects of most types
|
2002-05-19 06:55:13 +00:00
|
|
|
.IP \fIFunctions\fR
|
2002-05-19 06:17:52 +00:00
|
|
|
which return objects of a given type
|
2002-05-19 06:55:13 +00:00
|
|
|
.IP \fIPointers\fR
|
2002-05-19 06:17:52 +00:00
|
|
|
to objects of a given type
|
2002-05-19 06:55:13 +00:00
|
|
|
.IP \fIStructures\fR
|
2002-05-19 06:17:52 +00:00
|
|
|
containing a sequence of objects of various types
|
2002-05-19 06:55:13 +00:00
|
|
|
.IP \fIUnions\fR
|
2002-05-19 06:17:52 +00:00
|
|
|
capable of containing any one of several objects of various types.
|
2002-05-19 06:55:13 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
In general these methods
|
|
|
|
of constructing objects can
|
|
|
|
be applied recursively.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
Objects and Lvalues
|
|
|
|
.PP
|
|
|
|
An
|
|
|
|
.I
|
|
|
|
object
|
|
|
|
.R
|
|
|
|
is a manipulatable region of storage.
|
|
|
|
An
|
|
|
|
.I
|
|
|
|
lvalue
|
|
|
|
.R
|
|
|
|
is an expression referring to an object.
|
|
|
|
An obvious example of an lvalue
|
|
|
|
expression is an identifier.
|
|
|
|
There are operators which yield lvalues:
|
|
|
|
for example,
|
|
|
|
if
|
|
|
|
.B
|
|
|
|
E
|
|
|
|
.R
|
|
|
|
is an expression of pointer type, then
|
|
|
|
.B
|
|
|
|
\(**E
|
|
|
|
.R
|
|
|
|
is an lvalue
|
|
|
|
expression referring to the object to which
|
|
|
|
.B
|
|
|
|
E
|
|
|
|
.R
|
|
|
|
points.
|
|
|
|
The name ``lvalue'' comes from the assignment expression
|
|
|
|
.B
|
|
|
|
E1\ =\ E2
|
|
|
|
.R
|
|
|
|
in which the left operand
|
|
|
|
.B
|
|
|
|
E1
|
|
|
|
.R
|
|
|
|
must be
|
|
|
|
an lvalue expression.
|
|
|
|
The discussion of each operator
|
|
|
|
below indicates whether it expects lvalue operands and whether it
|
|
|
|
yields an lvalue.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
Conversions
|
|
|
|
.PP
|
|
|
|
A number of operators may, depending on their operands,
|
|
|
|
cause conversion of the value of an operand from one type to another.
|
|
|
|
This part explains the result to be expected from such
|
|
|
|
conversions.
|
|
|
|
The conversions demanded by most ordinary operators are summarized under
|
|
|
|
``Arithmetic Conversions.''
|
|
|
|
The summary will be supplemented
|
|
|
|
as required by the discussion
|
|
|
|
of each operator.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Characters and Integers
|
|
|
|
.PP
|
|
|
|
A character or a short integer may be used wherever an
|
|
|
|
integer may be used.
|
|
|
|
In all cases
|
|
|
|
the value is converted to an integer.
|
|
|
|
Conversion of a shorter integer
|
|
|
|
to a longer preserves sign.
|
|
|
|
Whether or not sign-extension occurs for characters is machine
|
|
|
|
dependent, but it is guaranteed that a member of the
|
|
|
|
standard character set is non-negative.
|
|
|
|
Of the machines treated here,
|
|
|
|
only the
|
|
|
|
PDP-11
|
|
|
|
and
|
|
|
|
VAX-11
|
|
|
|
sign-extend.
|
|
|
|
On these machines,
|
|
|
|
.B
|
|
|
|
char
|
|
|
|
.R
|
|
|
|
variables range in value from
|
|
|
|
\(mi128 to 127.
|
|
|
|
The more explicit type
|
|
|
|
.B
|
|
|
|
unsigned
|
|
|
|
.R
|
|
|
|
.B
|
|
|
|
char
|
|
|
|
.R
|
|
|
|
forces the values to range from 0 to 255.
|
|
|
|
.PP
|
|
|
|
On machines that treat characters as signed,
|
|
|
|
the characters of the
|
|
|
|
ASCII
|
|
|
|
set are all non-negative.
|
|
|
|
However, a character constant specified
|
|
|
|
with an octal escape suffers sign extension
|
|
|
|
and may appear negative;
|
|
|
|
for example,
|
|
|
|
\fB\'\e377\'\fR
|
|
|
|
\fRhas the value
|
|
|
|
.B
|
|
|
|
\(mi1\fR.
|
|
|
|
.PP
|
|
|
|
When a longer integer is converted to a shorter
|
|
|
|
integer
|
|
|
|
or to a
|
|
|
|
.B
|
|
|
|
char,
|
|
|
|
.R
|
|
|
|
it is truncated on the left.
|
|
|
|
Excess bits are simply discarded.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Float and Double
|
|
|
|
.PP
|
|
|
|
All floating arithmetic in C is carried out in double precision.
|
|
|
|
Whenever a
|
|
|
|
.B
|
|
|
|
float
|
|
|
|
.R
|
|
|
|
appears in an expression it is lengthened to
|
|
|
|
.B
|
|
|
|
double
|
|
|
|
.R
|
|
|
|
by zero padding its fraction.
|
|
|
|
When a
|
|
|
|
.B
|
|
|
|
double
|
|
|
|
.R
|
|
|
|
must be
|
|
|
|
converted to
|
|
|
|
\fBfloat\fR,
|
|
|
|
for example by an assignment,
|
|
|
|
the
|
|
|
|
.B
|
|
|
|
double
|
|
|
|
.R
|
|
|
|
is rounded before
|
|
|
|
truncation to
|
|
|
|
.B
|
|
|
|
float
|
|
|
|
.R
|
|
|
|
length.
|
|
|
|
This result is undefined if it cannot be represented as a float.
|
2002-10-12 14:50:50 +00:00
|
|
|
On the VAX, the compiler can be directed to use single precision for expressions
|
|
|
|
containing only float and integer operands.
|
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Floating and Integral
|
|
|
|
.PP
|
|
|
|
Conversions of floating values to integral type
|
|
|
|
are rather machine dependent.
|
|
|
|
In particular, the direction of truncation of negative numbers
|
|
|
|
varies.
|
|
|
|
The result is undefined if
|
|
|
|
it will not fit in the space provided.
|
|
|
|
.PP
|
|
|
|
Conversions of integral values to floating type
|
|
|
|
are well behaved.
|
|
|
|
Some loss of accuracy occurs
|
|
|
|
if the destination lacks sufficient bits.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Pointers and Integers
|
|
|
|
.PP
|
|
|
|
An expression of integral type may be added to or subtracted from
|
|
|
|
a pointer; in such a case,
|
|
|
|
the first is converted as
|
|
|
|
specified in the discussion of the addition operator.
|
|
|
|
Two pointers to objects of the same type may be subtracted;
|
|
|
|
in this case, the result is converted to an integer
|
|
|
|
as specified in the discussion of the subtraction
|
|
|
|
operator.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Unsigned
|
|
|
|
.PP
|
|
|
|
Whenever an unsigned integer and a plain integer
|
|
|
|
are combined, the plain integer is converted to unsigned
|
|
|
|
and the result is unsigned.
|
|
|
|
The value
|
|
|
|
is the least unsigned integer congruent to the signed
|
|
|
|
integer (modulo 2\v'-0.3'\s-2wordsize\s+2\v'0.3').
|
|
|
|
In a 2's complement representation,
|
|
|
|
this conversion is conceptual; and there is no actual change in the
|
|
|
|
bit pattern.
|
|
|
|
.PP
|
|
|
|
When an unsigned \fBshort\fR integer is converted to
|
|
|
|
\fBlong\fR,
|
|
|
|
the value of the result is the same numerically as that of the
|
|
|
|
unsigned integer.
|
|
|
|
Thus the conversion amounts to padding with zeros on the left.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Arithmetic Conversions
|
|
|
|
.PP
|
|
|
|
A great many operators cause conversions
|
|
|
|
and yield result types in a similar way.
|
|
|
|
This pattern will be called the ``usual arithmetic conversions.''
|
2002-05-19 06:55:13 +00:00
|
|
|
.IP 1.
|
2002-05-19 06:17:52 +00:00
|
|
|
First, any operands of type
|
|
|
|
.B
|
|
|
|
char
|
|
|
|
.R
|
|
|
|
or
|
|
|
|
.B
|
|
|
|
short
|
|
|
|
.R
|
|
|
|
are converted to
|
|
|
|
\fBint\fR,
|
|
|
|
and any operands of type \fBunsigned char\fR
|
|
|
|
or \fBunsigned short\fR are converted
|
|
|
|
to \fBunsigned int\fR.
|
2002-05-19 06:55:13 +00:00
|
|
|
.IP 2.
|
2002-05-19 06:17:52 +00:00
|
|
|
Then, if either operand is
|
|
|
|
.B
|
|
|
|
double,
|
|
|
|
.R
|
|
|
|
the other is converted to
|
|
|
|
.B
|
|
|
|
double
|
|
|
|
.R
|
|
|
|
and that is the type of the result.
|
2002-05-19 06:55:13 +00:00
|
|
|
.IP 3.
|
2002-05-19 06:17:52 +00:00
|
|
|
Otherwise, if either operand is \fBunsigned long\fR,
|
|
|
|
the other is converted to \fBunsigned long\fR and that
|
|
|
|
is the type of the result.
|
2002-05-19 06:55:13 +00:00
|
|
|
.IP 4.
|
2002-05-19 06:17:52 +00:00
|
|
|
Otherwise, if either operand is
|
|
|
|
\fBlong\fR,
|
|
|
|
the other is converted to
|
|
|
|
.B
|
|
|
|
long
|
|
|
|
.R
|
|
|
|
and that is the type of the result.
|
2002-05-19 06:55:13 +00:00
|
|
|
.IP 5.
|
2002-05-19 06:17:52 +00:00
|
|
|
Otherwise, if one operand is \fBlong\fR, and
|
|
|
|
the other is \fBunsigned int\fR, they are both
|
|
|
|
converted to \fBunsigned long\fR and that is
|
|
|
|
the type of the result.
|
2002-05-19 06:55:13 +00:00
|
|
|
.IP 6.
|
2002-05-19 06:17:52 +00:00
|
|
|
Otherwise, if either operand is
|
|
|
|
.B
|
|
|
|
unsigned,
|
|
|
|
.R
|
|
|
|
the other is converted to
|
|
|
|
.B
|
|
|
|
unsigned
|
|
|
|
.R
|
|
|
|
and that is the type of the result.
|
2002-05-19 06:55:13 +00:00
|
|
|
.IP 7.
|
2002-05-19 06:17:52 +00:00
|
|
|
Otherwise, both operands must be
|
|
|
|
\fBint\fR,
|
|
|
|
and that is the type of the result.
|
2002-05-19 06:55:13 +00:00
|
|
|
.LP
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Void
|
|
|
|
.PP
|
|
|
|
The (nonexistent) value of a
|
|
|
|
.B
|
|
|
|
void
|
|
|
|
.R
|
|
|
|
object may not be used in any way,
|
|
|
|
and neither explicit nor implicit conversion may be applied.
|
|
|
|
Because a void expression denotes a nonexistent value,
|
|
|
|
such an expression may be used only
|
|
|
|
as an expression statement
|
|
|
|
(see ``Expression Statement'' under ``STATEMENTS'')
|
|
|
|
or as the left operand
|
|
|
|
of a comma expression (see ``Comma Operator'' under ``EXPRESSIONS'').
|
|
|
|
.PP
|
|
|
|
An expression may be converted to
|
|
|
|
type
|
|
|
|
.B
|
|
|
|
void
|
|
|
|
.R
|
|
|
|
by use of a cast.
|
|
|
|
For example, this makes explicit the discarding of the value
|
|
|
|
of a function call used as an expression statement.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
Expressions
|
|
|
|
.PP
|
|
|
|
The precedence of expression operators is the same
|
|
|
|
as the order of the major
|
|
|
|
subsections of this section, highest precedence first.
|
|
|
|
Thus, for example, the expressions referred to as the operands of
|
|
|
|
.B
|
|
|
|
\(pl
|
|
|
|
.R
|
|
|
|
(see ``Additive Operators'')
|
|
|
|
are those expressions defined under ``Primary Expressions'',
|
|
|
|
``Unary Operators'', and ``Multiplicative Operators''.
|
|
|
|
Within each subpart, the operators have the same
|
|
|
|
precedence.
|
|
|
|
Left- or right-associativity is specified
|
|
|
|
in each subsection for the operators
|
|
|
|
discussed therein.
|
|
|
|
The precedence and associativity of all the expression
|
|
|
|
operators are summarized in the
|
|
|
|
grammar of ``SYNTAX SUMMARY''.
|
|
|
|
.PP
|
|
|
|
Otherwise, the order of evaluation of expressions
|
|
|
|
is undefined. In particular, the compiler
|
|
|
|
considers itself free to
|
|
|
|
compute subexpressions in the order it believes
|
|
|
|
most efficient
|
|
|
|
even if the subexpressions
|
|
|
|
involve side effects.
|
|
|
|
The order in which subexpression evaluation takes place is unspecified.
|
|
|
|
Expressions involving a commutative and associative
|
|
|
|
operator
|
|
|
|
(\fB\(**,\fR
|
|
|
|
\fB\(pl\fR,
|
|
|
|
\fB&\fR,
|
|
|
|
\fB|\fR,
|
|
|
|
\fB^\fR)
|
|
|
|
may be rearranged arbitrarily even in the presence
|
|
|
|
of parentheses;
|
|
|
|
to force a particular order of evaluation,
|
|
|
|
an explicit temporary must be used.
|
|
|
|
.PP
|
|
|
|
The handling of overflow and divide check
|
|
|
|
in expression evaluation
|
|
|
|
is undefined.
|
|
|
|
Most existing implementations of C ignore integer overflows;
|
|
|
|
treatment of
|
|
|
|
division by 0 and all floating-point exceptions
|
|
|
|
varies between machines and is usually
|
|
|
|
adjustable by a library function.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Primary Expressions
|
|
|
|
.PP
|
|
|
|
Primary expressions
|
|
|
|
involving \fB\.\fR,
|
|
|
|
\fB\(mi>\fR,
|
|
|
|
subscripting, and function calls
|
|
|
|
group left to right.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIprimary-expression:
|
|
|
|
identifier
|
|
|
|
constant
|
|
|
|
string
|
|
|
|
( expression )
|
|
|
|
primary-expression [ expression ]
|
|
|
|
primary-expression ( expression-list\v'0.5'\s-2opt\s0\v'-0.5' )
|
|
|
|
primary-expression . identifier
|
|
|
|
primary-expression \(mi> identifier\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIexpression-list:
|
|
|
|
expression
|
|
|
|
expression-list , expression\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
An identifier is a primary expression provided it has been
|
|
|
|
suitably declared as discussed below.
|
|
|
|
Its type is specified by its declaration.
|
|
|
|
If the type of the identifier is ``array of .\|.\|.'',
|
|
|
|
then the value of the identifier expression
|
|
|
|
is a pointer
|
|
|
|
to the first object in the array; and the
|
|
|
|
type of the expression is
|
|
|
|
``pointer to .\|.\|.''.
|
|
|
|
Moreover, an array identifier is not an lvalue
|
|
|
|
expression.
|
|
|
|
Likewise, an identifier which is declared
|
|
|
|
``function returning .\|.\|.'',
|
|
|
|
when used except in the function-name position
|
|
|
|
of a call, is converted to ``pointer to function returning .\|.\|.''.
|
|
|
|
.PP
|
|
|
|
A
|
|
|
|
constant is a primary expression.
|
|
|
|
Its type may be
|
|
|
|
\fBint\fR,
|
|
|
|
\fBlong\fR,
|
|
|
|
or
|
|
|
|
.B
|
|
|
|
double
|
|
|
|
.R
|
|
|
|
depending on its form.
|
|
|
|
Character constants have type
|
|
|
|
.B
|
2002-10-12 14:50:50 +00:00
|
|
|
int
|
2002-05-19 06:17:52 +00:00
|
|
|
.R
|
|
|
|
and floating constants have type
|
|
|
|
.B
|
|
|
|
double\fR.
|
|
|
|
.R
|
|
|
|
.PP
|
|
|
|
A string is a primary expression.
|
|
|
|
Its type is originally ``array of
|
|
|
|
\fBchar\fR'',
|
|
|
|
but following
|
|
|
|
the same rule given above for identifiers,
|
|
|
|
this is modified to ``pointer to
|
|
|
|
\fBchar\fR'' and
|
|
|
|
the
|
|
|
|
result is a pointer to the first character
|
|
|
|
in the string.
|
|
|
|
(There is an exception in certain initializers;
|
|
|
|
see ``Initialization'' under ``DECLARATIONS.'')
|
|
|
|
.PP
|
|
|
|
A parenthesized expression is a primary expression
|
|
|
|
whose type and value are identical
|
|
|
|
to those of the unadorned expression.
|
|
|
|
The presence of parentheses does
|
|
|
|
not affect whether the expression is an
|
|
|
|
lvalue.
|
|
|
|
.PP
|
|
|
|
A primary expression followed by an expression in square
|
|
|
|
brackets is a primary expression.
|
|
|
|
The intuitive meaning is that of a subscript.
|
|
|
|
Usually, the primary expression has type ``pointer to .\|.\|.'',
|
|
|
|
the subscript expression is
|
|
|
|
\fBint\fR,
|
|
|
|
and the type of the result is ``\|.\|.\|.\|''.
|
|
|
|
The expression
|
|
|
|
.B
|
|
|
|
E1[E2]
|
|
|
|
.R
|
|
|
|
is
|
|
|
|
identical (by definition) to
|
|
|
|
.B
|
|
|
|
\(**((E1)\(plE2))\fR.
|
|
|
|
All the clues
|
|
|
|
needed to understand
|
|
|
|
this notation are contained in this subpart together
|
|
|
|
with the discussions
|
|
|
|
in ``Unary Operators'' and ``Additive Operators'' on identifiers,
|
|
|
|
.B
|
2002-10-12 14:50:50 +00:00
|
|
|
\(**
|
2002-05-19 06:17:52 +00:00
|
|
|
.R
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
\(pl
|
|
|
|
.R
|
|
|
|
respectively.
|
|
|
|
The implications are summarized under ``Arrays, Pointers, and Subscripting''
|
|
|
|
under ``TYPES REVISITED.''
|
|
|
|
.PP
|
|
|
|
A function call is a primary expression followed by parentheses
|
|
|
|
containing a possibly
|
|
|
|
empty, comma-separated list of expressions
|
|
|
|
which constitute the actual arguments to the
|
|
|
|
function.
|
|
|
|
The primary expression must be of type ``function returning .\|.\|.,''
|
|
|
|
and the result of the function call is of type ``\|.\|.\|.\|''.
|
|
|
|
As indicated
|
|
|
|
below, a hitherto unseen identifier followed
|
|
|
|
immediately by a left parenthesis
|
|
|
|
is contextually declared
|
|
|
|
to represent a function returning
|
|
|
|
an integer;
|
|
|
|
thus in the most common case, integer-valued functions
|
|
|
|
need not be declared.
|
|
|
|
.PP
|
|
|
|
Any actual arguments of type
|
|
|
|
.B
|
|
|
|
float
|
|
|
|
.R
|
|
|
|
are
|
|
|
|
converted to
|
|
|
|
.B
|
|
|
|
double
|
|
|
|
.R
|
|
|
|
before the call.
|
|
|
|
Any of type
|
|
|
|
.B
|
|
|
|
char
|
|
|
|
.R
|
|
|
|
or
|
|
|
|
.B
|
|
|
|
short
|
|
|
|
.R
|
|
|
|
are converted to
|
|
|
|
.B
|
|
|
|
int\fR.
|
|
|
|
.R
|
|
|
|
Array names are converted to pointers.
|
|
|
|
No other conversions are performed automatically;
|
|
|
|
in particular, the compiler does not compare
|
|
|
|
the types of actual arguments with those of formal
|
|
|
|
arguments.
|
|
|
|
If conversion is needed, use a cast;
|
|
|
|
see ``Unary Operators'' and ``Type Names'' under
|
|
|
|
``DECLARATIONS.''
|
|
|
|
.PP
|
|
|
|
In preparing for the call to a function,
|
|
|
|
a copy is made of each actual parameter.
|
|
|
|
Thus, all argument passing in C is strictly by value.
|
|
|
|
A function may
|
|
|
|
change the values of its formal parameters, but
|
|
|
|
these changes cannot affect the values
|
|
|
|
of the actual parameters.
|
|
|
|
It is possible
|
|
|
|
to pass a pointer on the understanding
|
|
|
|
that the function may change the value
|
|
|
|
of the object to which the pointer points.
|
|
|
|
An array name is a pointer expression.
|
|
|
|
The order of evaluation of arguments is undefined by the language;
|
|
|
|
take note that the various compilers differ.
|
|
|
|
Recursive calls to any
|
|
|
|
function are permitted.
|
|
|
|
.PP
|
|
|
|
A primary expression followed by a dot followed by an identifier
|
|
|
|
is an expression.
|
|
|
|
The first expression must be a structure or a union, and the identifier
|
|
|
|
must name a member of the structure or union.
|
|
|
|
The value is the named member of the structure or union, and it is
|
|
|
|
an lvalue if the first expression is an lvalue.
|
|
|
|
.PP
|
|
|
|
A primary expression followed by an arrow (built from
|
|
|
|
.B
|
|
|
|
\(mi
|
|
|
|
.R
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
>
|
|
|
|
.R
|
|
|
|
)
|
|
|
|
followed by an identifier
|
|
|
|
is an expression.
|
|
|
|
The first expression must be a pointer to a structure or a union
|
|
|
|
and the identifier must name a member of that structure or union.
|
|
|
|
The result is an lvalue referring to the named member
|
|
|
|
of the structure or union
|
|
|
|
to which the pointer expression points.
|
|
|
|
Thus the expression
|
|
|
|
.B
|
|
|
|
E1\(mi>MOS
|
|
|
|
.R
|
|
|
|
is the same as
|
|
|
|
.B
|
|
|
|
(\(**E1).MOS\fR.
|
|
|
|
.R
|
|
|
|
Structures and unions are discussed in
|
|
|
|
``Structure, Union, and Enumeration Declarations'' under
|
|
|
|
``DECLARATIONS.''
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Unary Operators
|
|
|
|
.PP
|
|
|
|
Expressions with unary operators
|
|
|
|
group right to left.
|
|
|
|
.tr ~~
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIunary-expression:
|
|
|
|
\(** expression
|
|
|
|
& lvalue
|
|
|
|
\(mi expression
|
|
|
|
! expression
|
|
|
|
\s+2~\s0 expression
|
|
|
|
\(pl\(pl lvalue
|
|
|
|
\(mi\(milvalue
|
|
|
|
lvalue \(pl\(pl
|
|
|
|
lvalue \(mi\(mi
|
|
|
|
( type-name ) expression\fR
|
|
|
|
sizeof\fI expression\fR
|
|
|
|
sizeof\fI ( type-name )\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The unary
|
|
|
|
.B
|
|
|
|
\(**
|
|
|
|
.R
|
|
|
|
operator
|
|
|
|
means
|
|
|
|
.I
|
|
|
|
indirection
|
|
|
|
.R
|
|
|
|
;
|
|
|
|
the expression must be a pointer, and the result
|
|
|
|
is an lvalue referring to the object to
|
|
|
|
which the expression points.
|
|
|
|
If the type of the expression is ``pointer to .\|.\|.,''
|
|
|
|
the type of the result is ``\|.\|.\|.\|''.
|
|
|
|
.PP
|
|
|
|
The result of the unary
|
|
|
|
.B
|
|
|
|
&
|
|
|
|
.R
|
|
|
|
operator is a pointer
|
|
|
|
to the object referred to by the
|
|
|
|
lvalue.
|
|
|
|
If the type of the lvalue is ``\|.\|.\|.\|'',
|
|
|
|
the type of the result is ``pointer to .\|.\|.''.
|
|
|
|
.PP
|
|
|
|
The result
|
|
|
|
of the unary
|
|
|
|
.B
|
|
|
|
\(mi
|
|
|
|
.R
|
|
|
|
operator
|
|
|
|
is the negative of its operand.
|
|
|
|
The usual arithmetic conversions are performed.
|
|
|
|
The negative of an unsigned quantity is computed by
|
|
|
|
subtracting its value from
|
|
|
|
2\v'-0.5'\fIn\fR\^\v'0.5' where \fIn\fR\^ is the number of bits in
|
|
|
|
the corresponding signed type.
|
|
|
|
.sp
|
|
|
|
.tr ~~
|
|
|
|
There is no unary
|
|
|
|
.B
|
|
|
|
\(pl
|
|
|
|
.R
|
|
|
|
operator.
|
|
|
|
.PP
|
|
|
|
The result of the logical negation operator
|
|
|
|
.B
|
|
|
|
!
|
|
|
|
.R
|
|
|
|
is one if the value of its operand is zero, zero if the value of its
|
|
|
|
operand is nonzero.
|
|
|
|
The type of the result is
|
|
|
|
.B
|
|
|
|
int\fR.
|
|
|
|
.R
|
|
|
|
It is applicable to any arithmetic type
|
|
|
|
or to pointers.
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
\s+2~\s0
|
|
|
|
.R
|
|
|
|
operator yields the one's complement of its operand.
|
|
|
|
The usual arithmetic conversions are performed.
|
|
|
|
The type of the operand must be integral.
|
|
|
|
.PP
|
|
|
|
The object referred to by the lvalue operand of prefix
|
|
|
|
.B
|
|
|
|
\(pl\(pl
|
|
|
|
.R
|
|
|
|
is incremented.
|
|
|
|
The value is the new value of the operand
|
|
|
|
but is not an lvalue.
|
|
|
|
The expression
|
|
|
|
.B
|
|
|
|
\(pl\(plx
|
|
|
|
.R
|
|
|
|
is equivalent to
|
|
|
|
\fBx=x\(pl1\fR.
|
|
|
|
See the discussions ``Additive Operators'' and ``Assignment
|
|
|
|
Operators'' for information on conversions.
|
|
|
|
.PP
|
|
|
|
The lvalue operand of prefix
|
|
|
|
.B
|
|
|
|
\(mi\(mi
|
|
|
|
.R
|
|
|
|
is decremented
|
|
|
|
analogously to the
|
|
|
|
prefix
|
|
|
|
.B
|
|
|
|
\(pl\(pl
|
|
|
|
.R
|
|
|
|
operator.
|
|
|
|
.PP
|
|
|
|
When postfix
|
|
|
|
.B
|
|
|
|
\(pl\(pl
|
|
|
|
.R
|
|
|
|
is applied to an lvalue,
|
|
|
|
the result is the value of the object referred to by the lvalue.
|
|
|
|
After the result is noted, the object
|
|
|
|
is incremented in the same
|
|
|
|
manner as for the prefix
|
|
|
|
.B
|
|
|
|
\(pl\(pl
|
|
|
|
.R
|
|
|
|
operator.
|
|
|
|
The type of the result is the same as the type of the lvalue expression.
|
|
|
|
.PP
|
|
|
|
When postfix
|
|
|
|
.B
|
|
|
|
\(mi\(mi
|
|
|
|
.R
|
|
|
|
is applied to an lvalue,
|
|
|
|
the result is the value of the object referred to by the lvalue.
|
|
|
|
After the result is noted, the object
|
|
|
|
is decremented in the manner as for the prefix
|
|
|
|
.B
|
|
|
|
\(mi\(mi
|
|
|
|
.R
|
|
|
|
operator.
|
|
|
|
The type of the result is the same as the type of the lvalue
|
|
|
|
expression.
|
|
|
|
.PP
|
|
|
|
An expression preceded by the parenthesized name of a data type
|
|
|
|
causes conversion of the value of the expression to the named type.
|
|
|
|
This construction is called a
|
|
|
|
.I
|
|
|
|
cast\fR.
|
|
|
|
.R
|
|
|
|
Type names are described in ``Type Names'' under ``Declarations.''
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
sizeof
|
|
|
|
.R
|
|
|
|
operator yields the size
|
|
|
|
in bytes of its operand.
|
|
|
|
(A
|
|
|
|
.I
|
|
|
|
byte
|
|
|
|
.R
|
|
|
|
is undefined by the language
|
|
|
|
except in terms of the value of
|
|
|
|
.B
|
|
|
|
sizeof\fR.
|
|
|
|
.R
|
|
|
|
However, in all existing implementations,
|
|
|
|
a byte is the space required to hold a
|
|
|
|
\fBchar.\fR)
|
|
|
|
When applied to an array, the result is the total
|
|
|
|
number of bytes in the array.
|
|
|
|
The size is determined from
|
|
|
|
the declarations of
|
|
|
|
the objects in the expression.
|
|
|
|
This expression is semantically an
|
|
|
|
.B
|
|
|
|
unsigned
|
|
|
|
.R
|
|
|
|
constant and may
|
|
|
|
be used anywhere a constant is required.
|
|
|
|
Its major use is in communication with routines
|
|
|
|
like storage allocators and I/O systems.
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
sizeof
|
|
|
|
.R
|
|
|
|
operator
|
|
|
|
may also be applied to a parenthesized type name.
|
|
|
|
In that case it yields the size in bytes of an object
|
|
|
|
of the indicated type.
|
|
|
|
.PP
|
|
|
|
The construction
|
|
|
|
\fBsizeof(\fItype\|\fR\^)\fR\^
|
|
|
|
is taken to be a unit,
|
|
|
|
so the expression
|
|
|
|
\fBsizeof(\fItype\|\fB)-2\fR
|
|
|
|
is the same as
|
|
|
|
\fB(sizeof(\fItype\|\fB))-2\fR.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Multiplicative Operators
|
|
|
|
.PP
|
|
|
|
The multiplicative operators
|
|
|
|
\fB\(**\fR,
|
|
|
|
\fB/\fR,
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
%
|
|
|
|
.R
|
|
|
|
group left to right.
|
|
|
|
The usual arithmetic conversions are performed.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fImultiplicative expression:
|
|
|
|
expression \(** expression
|
|
|
|
expression / expression
|
|
|
|
expression % expression\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The binary
|
|
|
|
.B
|
|
|
|
\(**
|
|
|
|
.R
|
|
|
|
operator indicates multiplication.
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
\(**
|
|
|
|
.R
|
|
|
|
operator is associative,
|
|
|
|
and expressions with several multiplications at the same
|
|
|
|
level may be rearranged by the compiler.
|
|
|
|
The binary
|
|
|
|
.B
|
|
|
|
/
|
|
|
|
.R
|
|
|
|
operator indicates division.
|
|
|
|
.PP
|
|
|
|
The binary
|
|
|
|
.B
|
|
|
|
%
|
|
|
|
.R
|
|
|
|
operator yields the remainder
|
|
|
|
from the division of the first expression by the second.
|
|
|
|
The operands must be integral.
|
|
|
|
.PP
|
|
|
|
When positive integers are divided, truncation is toward 0;
|
|
|
|
but the form of truncation is machine-dependent
|
|
|
|
if either operand is negative.
|
|
|
|
On all machines covered by this manual,
|
|
|
|
the remainder has the same sign as the dividend.
|
|
|
|
It is always true that
|
|
|
|
.B
|
|
|
|
(a/b)\(**b\ \(pl a%b
|
|
|
|
.R
|
|
|
|
is equal to
|
|
|
|
.B
|
|
|
|
a
|
|
|
|
.R
|
|
|
|
(if
|
|
|
|
.B
|
|
|
|
b
|
|
|
|
.R
|
|
|
|
is not 0).
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Additive Operators
|
|
|
|
.PP
|
|
|
|
The additive operators
|
|
|
|
.B
|
|
|
|
\(pl
|
|
|
|
.R
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
\(mi
|
|
|
|
.R
|
|
|
|
group left to right.
|
|
|
|
The usual arithmetic conversions are performed.
|
|
|
|
There are some additional type possibilities for each operator.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIadditive-expression:
|
|
|
|
expression \(pl expression
|
|
|
|
expression \(mi expression\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The result of the
|
|
|
|
.B
|
|
|
|
\(pl
|
|
|
|
.R
|
|
|
|
operator is the sum of the operands.
|
|
|
|
A pointer to an object in an array and
|
|
|
|
a value of any integral type
|
|
|
|
may be added.
|
|
|
|
The latter is in all cases converted to
|
|
|
|
an address offset
|
|
|
|
by multiplying it
|
|
|
|
by the length of the object to which the
|
|
|
|
pointer points.
|
|
|
|
The result is a pointer
|
|
|
|
of the same type as the original pointer
|
|
|
|
which points to another object in the same array,
|
|
|
|
appropriately offset from the original object.
|
|
|
|
Thus if
|
|
|
|
.B
|
|
|
|
P
|
|
|
|
.R
|
|
|
|
is a pointer
|
|
|
|
to an object in an array, the expression
|
|
|
|
.B
|
|
|
|
P\(pl1
|
|
|
|
.R
|
|
|
|
is a pointer
|
|
|
|
to the next object in the array.
|
|
|
|
No further type combinations are allowed for pointers.
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
\(pl
|
|
|
|
.R
|
|
|
|
operator is associative,
|
|
|
|
and expressions with several additions at the same level may
|
|
|
|
be rearranged by the compiler.
|
|
|
|
.PP
|
|
|
|
The result of the
|
|
|
|
.B
|
|
|
|
\(mi
|
|
|
|
.R
|
|
|
|
operator is the difference of the operands.
|
|
|
|
The usual arithmetic conversions are performed.
|
|
|
|
Additionally,
|
|
|
|
a value of any integral type
|
|
|
|
may be subtracted from a pointer,
|
|
|
|
and then the same conversions for addition apply.
|
|
|
|
.PP
|
|
|
|
If two pointers to objects of the same type are subtracted,
|
|
|
|
the result is converted
|
|
|
|
(by division by the length of the object)
|
|
|
|
to an
|
|
|
|
.B
|
|
|
|
int
|
|
|
|
.R
|
|
|
|
representing the number of
|
|
|
|
objects separating
|
|
|
|
the pointed-to objects.
|
|
|
|
This conversion will in general give unexpected
|
|
|
|
results unless the pointers point
|
|
|
|
to objects in the same array, since pointers, even
|
|
|
|
to objects of the same type, do not necessarily differ
|
|
|
|
by a multiple of the object length.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Shift Operators
|
|
|
|
.PP
|
|
|
|
The shift operators
|
|
|
|
.B
|
|
|
|
<<
|
|
|
|
.R
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
>>
|
|
|
|
.R
|
|
|
|
group left to right.
|
|
|
|
Both perform the usual arithmetic conversions on their operands,
|
|
|
|
each of which must be integral.
|
|
|
|
Then the right operand is converted to
|
|
|
|
\fBint\fR;
|
|
|
|
the type of the result is that of the left operand.
|
|
|
|
The result is undefined if the right operand is negative
|
|
|
|
or greater than or equal to the length of the object in bits.
|
|
|
|
On the VAX a negative right operand is interpreted as reversing
|
|
|
|
the direction of the shift.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIshift-expression:
|
|
|
|
expression << expression
|
|
|
|
expression >> expression\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The value of
|
|
|
|
.B
|
|
|
|
E1<<E2
|
|
|
|
.R
|
|
|
|
is
|
|
|
|
.B
|
|
|
|
E1
|
|
|
|
.R
|
|
|
|
(interpreted as a bit
|
|
|
|
pattern) left-shifted
|
|
|
|
.B
|
|
|
|
E2
|
|
|
|
.R
|
|
|
|
bits.
|
|
|
|
Vacated bits are 0 filled.
|
|
|
|
The value of
|
|
|
|
.B
|
|
|
|
E1>>E2
|
|
|
|
.R
|
|
|
|
is
|
|
|
|
.B
|
|
|
|
E1
|
|
|
|
.R
|
|
|
|
right-shifted
|
|
|
|
.B
|
|
|
|
E2
|
|
|
|
.R
|
|
|
|
bit positions.
|
|
|
|
The right shift is guaranteed to be logical
|
|
|
|
(0 fill)
|
|
|
|
if
|
|
|
|
.B
|
|
|
|
E1
|
|
|
|
.R
|
|
|
|
is
|
|
|
|
\fBunsigned\fR;
|
|
|
|
otherwise, it may be
|
|
|
|
arithmetic.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Relational Operators
|
|
|
|
.PP
|
2002-10-12 14:50:50 +00:00
|
|
|
The relational operators group left to right.
|
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIrelational-expression:
|
|
|
|
expression < expression
|
|
|
|
expression > expression
|
|
|
|
expression <= expression
|
|
|
|
expression >= expression\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The operators
|
|
|
|
.B
|
|
|
|
<
|
|
|
|
.R
|
|
|
|
(less than),
|
|
|
|
.B
|
|
|
|
>
|
|
|
|
.R
|
|
|
|
(greater than), \fB<=\fR
|
|
|
|
(less than
|
|
|
|
or equal to), and
|
|
|
|
.B
|
|
|
|
>=
|
|
|
|
.R
|
|
|
|
(greater than or equal to)
|
|
|
|
all yield 0 if the specified relation is false
|
|
|
|
and 1 if it is true.
|
|
|
|
The type of the result is
|
|
|
|
.B
|
|
|
|
int\fR.
|
|
|
|
The usual arithmetic conversions are performed.
|
|
|
|
Two pointers may be compared;
|
|
|
|
the result depends on the relative locations in the address space
|
|
|
|
of the pointed-to objects.
|
|
|
|
Pointer comparison is portable only when the pointers point to objects
|
|
|
|
in the same array.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Equality Operators
|
|
|
|
.PP
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIequality-expression:
|
|
|
|
expression == expression
|
|
|
|
expression != expression\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
==
|
|
|
|
.R
|
|
|
|
(equal to) and the
|
|
|
|
.B
|
|
|
|
!=
|
|
|
|
.R
|
|
|
|
(not equal to) operators
|
|
|
|
are exactly analogous to the relational
|
|
|
|
operators except for their lower
|
|
|
|
precedence.
|
|
|
|
(Thus
|
|
|
|
.B
|
|
|
|
a<b\ ==\ c<d
|
|
|
|
.R
|
|
|
|
is 1 whenever
|
|
|
|
.B
|
|
|
|
a<b
|
|
|
|
.R
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
c<d
|
|
|
|
.R
|
|
|
|
have the same truth value).
|
|
|
|
.PP
|
|
|
|
A pointer may be compared to an integer
|
|
|
|
only if the
|
|
|
|
integer is the constant 0.
|
|
|
|
A pointer to which 0 has been assigned is guaranteed
|
|
|
|
not to point to any object
|
|
|
|
and will appear to be equal to 0.
|
|
|
|
In conventional usage, such a pointer is considered to be null.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Bitwise \s-1AND\s0 Operator
|
|
|
|
.PP
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIand-expression:
|
|
|
|
expression & expression\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
&
|
|
|
|
.R
|
|
|
|
operator is associative,
|
|
|
|
and expressions involving
|
|
|
|
.B
|
|
|
|
&
|
|
|
|
.R
|
|
|
|
may be rearranged.
|
|
|
|
The usual arithmetic conversions are performed.
|
|
|
|
The result is the bitwise
|
|
|
|
AND
|
|
|
|
function of the operands.
|
|
|
|
The operator applies only to integral
|
|
|
|
operands.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Bitwise Exclusive \s-1OR\s0 Operator
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIexclusive-or-expression:
|
|
|
|
expression ^ expression\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
^
|
|
|
|
.R
|
|
|
|
operator is associative,
|
|
|
|
and expressions involving
|
|
|
|
.B
|
|
|
|
^
|
|
|
|
.R
|
|
|
|
may be rearranged.
|
|
|
|
The usual arithmetic conversions are performed;
|
|
|
|
the result is
|
|
|
|
the bitwise exclusive
|
|
|
|
OR
|
|
|
|
function of
|
|
|
|
the operands.
|
|
|
|
The operator applies only to integral
|
|
|
|
operands.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Bitwise Inclusive \s-1OR\s0 Operator
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIinclusive-or-expression:
|
|
|
|
expression | expression\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
|
|
|
|
|
.R
|
|
|
|
operator is associative,
|
|
|
|
and expressions involving
|
|
|
|
.B
|
|
|
|
|
|
|
|
|
.R
|
|
|
|
may be rearranged.
|
|
|
|
The usual arithmetic conversions are performed;
|
|
|
|
the result is the bitwise inclusive
|
|
|
|
OR
|
|
|
|
function of its operands.
|
|
|
|
The operator applies only to integral
|
|
|
|
operands.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Logical \s-1AND\s0 Operator
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIlogical-and-expression:
|
|
|
|
expression && expression\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
&&
|
|
|
|
.R
|
|
|
|
operator groups left to right.
|
|
|
|
It returns 1 if both its operands
|
|
|
|
evaluate to nonzero, 0 otherwise.
|
|
|
|
Unlike
|
|
|
|
\fB&\fR,
|
|
|
|
.B
|
|
|
|
&&
|
|
|
|
.R
|
|
|
|
guarantees left to right
|
|
|
|
evaluation; moreover, the second operand is not evaluated
|
|
|
|
if the first operand is 0.
|
|
|
|
.PP
|
|
|
|
The operands need not have the same type, but each
|
|
|
|
must have one of the fundamental
|
|
|
|
types or be a pointer.
|
|
|
|
The result is always
|
|
|
|
.B
|
|
|
|
int\fR.
|
|
|
|
.R
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Logical \s-1OR\s0 Operator
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIlogical-or-expression:
|
|
|
|
expression || expression\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
||
|
|
|
|
.R
|
|
|
|
operator groups left to right.
|
|
|
|
It returns 1 if either of its operands
|
|
|
|
evaluates to nonzero, 0 otherwise.
|
|
|
|
Unlike
|
|
|
|
\fB|\fR,
|
|
|
|
.B
|
|
|
|
||
|
|
|
|
.R
|
|
|
|
guarantees left to right evaluation; moreover,
|
|
|
|
the second operand is not evaluated
|
|
|
|
if the value of the first operand is nonzero.
|
|
|
|
.PP
|
|
|
|
The operands need not have the same type, but each
|
|
|
|
must
|
|
|
|
have one of the fundamental types
|
|
|
|
or be a pointer.
|
|
|
|
The result is always
|
|
|
|
.B
|
|
|
|
int\fR.
|
|
|
|
.R
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Conditional Operator
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIconditional-expression:
|
|
|
|
expression ? expression : expression\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
Conditional expressions group right to left.
|
|
|
|
The first expression is evaluated;
|
|
|
|
and if it is nonzero, the result is the value of the
|
|
|
|
second expression, otherwise that of third expression.
|
|
|
|
If possible, the usual arithmetic conversions are performed
|
|
|
|
to bring the second and third expressions to a common type.
|
|
|
|
If both are structures or unions of the same type,
|
|
|
|
the result has the type of the structure or union.
|
|
|
|
If both pointers are of the same type,
|
|
|
|
the result has the common type.
|
|
|
|
Otherwise, one must be a pointer and the other the constant 0,
|
|
|
|
and the result has the type of the pointer.
|
|
|
|
Only one of the second and third
|
|
|
|
expressions is evaluated.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Assignment Operators
|
|
|
|
.PP
|
|
|
|
There are a number of assignment operators,
|
|
|
|
all of which group right to left.
|
|
|
|
All require an lvalue as their left operand,
|
|
|
|
and the type of an assignment expression is that
|
|
|
|
of its left operand.
|
|
|
|
The value is the value stored in the
|
|
|
|
left operand after the assignment has taken place.
|
|
|
|
The two parts of a compound assignment operator are separate
|
|
|
|
tokens.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIassignment-expression:
|
|
|
|
lvalue = expression
|
|
|
|
lvalue \(pl= expression
|
|
|
|
lvalue \(mi= expression
|
|
|
|
lvalue \(**= expression
|
|
|
|
lvalue /= expression
|
|
|
|
lvalue %= expression
|
|
|
|
lvalue >>= expression
|
|
|
|
lvalue <<= expression
|
|
|
|
lvalue &= expression
|
|
|
|
lvalue ^= expression
|
|
|
|
lvalue |= expression\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
In the simple assignment with
|
|
|
|
\fB=\fR,
|
|
|
|
the value of the expression replaces that of the object
|
|
|
|
referred
|
|
|
|
to by the lvalue.
|
|
|
|
If both operands have arithmetic type,
|
|
|
|
the right operand is converted to the type of the left
|
|
|
|
preparatory to the assignment.
|
|
|
|
Second, both operands may be structures or unions of the same type.
|
|
|
|
Finally, if the left operand is a pointer, the right operand must in general be a pointer
|
|
|
|
of the same type.
|
|
|
|
However, the constant 0 may be assigned to a pointer;
|
|
|
|
it is guaranteed that this value will produce a null
|
|
|
|
pointer distinguishable from a pointer to any object.
|
|
|
|
.PP
|
|
|
|
The behavior of an expression
|
|
|
|
of the form
|
|
|
|
\fBE1\fR\^ \fIop\fR\^ = \fBE2\fR\^
|
|
|
|
may be inferred by
|
|
|
|
taking it as equivalent to
|
|
|
|
\fBE1 = E1 \fIop\fR\^ (\fBE2\fR\^);
|
|
|
|
however,
|
|
|
|
.B
|
|
|
|
E1
|
|
|
|
.R
|
|
|
|
is evaluated only once.
|
|
|
|
In
|
|
|
|
.B
|
|
|
|
\(pl=
|
|
|
|
.R
|
|
|
|
and
|
|
|
|
\fB\(mi=\fR,
|
|
|
|
the left operand may be a pointer; in which case, the (integral) right
|
|
|
|
operand is converted as explained
|
|
|
|
in ``Additive Operators.''
|
|
|
|
All right operands and all nonpointer left operands must
|
|
|
|
have arithmetic type.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Comma Operator
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIcomma-expression:
|
|
|
|
expression , expression\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
A pair of expressions separated by a comma is evaluated
|
|
|
|
left to right, and the value of the left expression is
|
|
|
|
discarded.
|
|
|
|
The type and value of the result are the
|
|
|
|
type and value of the right operand.
|
|
|
|
This operator groups left to right.
|
|
|
|
In contexts where comma is given a special meaning,
|
|
|
|
e.g., in lists of actual arguments
|
|
|
|
to functions (see ``Primary Expressions'') and lists
|
|
|
|
of initializers (see ``Initialization'' under ``DECLARATIONS''),
|
|
|
|
the comma operator as described in this subpart
|
|
|
|
can only appear in parentheses. For example,
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBf(a, (t=3, t\(pl2), c)\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
has three arguments, the second of which has the value 5.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
Declarations
|
|
|
|
.PP
|
|
|
|
Declarations are used to specify the interpretation
|
|
|
|
which C gives to each identifier; they do not necessarily
|
|
|
|
reserve storage associated with the identifier.
|
|
|
|
Declarations have the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIdeclaration:
|
|
|
|
decl-specifiers declarator-list\v'0.5'\s-2opt\s0\v'-0.5' ;\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
The declarators in the declarator-list
|
|
|
|
contain the identifiers being declared.
|
|
|
|
The decl-specifiers
|
|
|
|
consist of a sequence of type and storage class specifiers.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIdecl-specifiers:
|
|
|
|
type-specifier decl-specifiers\v'0.5'\s-2opt\s0\v'-0.5'
|
|
|
|
sc-specifier decl-specifiers\v'0.5'\s-2opt\s0\v'-0.5'\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
The list must be self-consistent in a way described below.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Storage Class Specifiers
|
|
|
|
.PP
|
|
|
|
The sc-specifiers are:
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIsc-specifier:\fB
|
|
|
|
auto
|
|
|
|
static
|
|
|
|
extern
|
|
|
|
register
|
|
|
|
typedef\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
The
|
|
|
|
.B
|
|
|
|
typedef
|
|
|
|
.R
|
|
|
|
specifier does not reserve storage
|
|
|
|
and is called a ``storage class specifier'' only for syntactic convenience.
|
|
|
|
See ``Typedef'' for more information.
|
|
|
|
The meanings of the various storage classes were discussed in ``Names.''
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
\fBauto\fR,
|
|
|
|
\fBstatic\fR,
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
register
|
|
|
|
.R
|
|
|
|
declarations also serve as definitions
|
|
|
|
in that they cause an appropriate amount of storage to be reserved.
|
|
|
|
In the
|
|
|
|
.B
|
|
|
|
extern
|
|
|
|
.R
|
|
|
|
case,
|
|
|
|
there must be an external definition (see ``External Definitions'')
|
|
|
|
for the given identifiers
|
|
|
|
somewhere outside the function in which they are declared.
|
|
|
|
.PP
|
|
|
|
A
|
|
|
|
.B
|
|
|
|
register
|
|
|
|
.R
|
|
|
|
declaration is best thought of as an
|
|
|
|
.B
|
|
|
|
auto
|
|
|
|
.R
|
|
|
|
declaration, together with a hint to the compiler
|
|
|
|
that the variables declared will be heavily used.
|
|
|
|
Only the first few
|
|
|
|
such declarations in each function are effective.
|
|
|
|
Moreover, only variables of certain types will be stored in registers;
|
|
|
|
on the
|
|
|
|
PDP-11,
|
|
|
|
they are
|
|
|
|
.B
|
|
|
|
int
|
|
|
|
.R
|
|
|
|
or pointer.
|
|
|
|
One other restriction applies to register variables:
|
|
|
|
the address-of operator
|
|
|
|
.B
|
|
|
|
&
|
|
|
|
.R
|
|
|
|
cannot be applied to them.
|
|
|
|
Smaller, faster programs can be expected if register declarations
|
|
|
|
are used appropriately,
|
|
|
|
but future improvements in code generation
|
|
|
|
may render them unnecessary.
|
|
|
|
.PP
|
|
|
|
At most, one sc-specifier may be given in a declaration.
|
|
|
|
If the sc-specifier is missing from a declaration, it
|
|
|
|
is taken to be
|
|
|
|
.B
|
|
|
|
auto
|
|
|
|
.R
|
|
|
|
inside a function,
|
|
|
|
.B
|
|
|
|
extern
|
|
|
|
.R
|
|
|
|
outside.
|
|
|
|
Exception:
|
|
|
|
functions are never
|
|
|
|
automatic.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Type Specifiers
|
|
|
|
.PP
|
|
|
|
The type-specifiers are
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fItype-specifier:
|
|
|
|
struct-or-union-specifier
|
|
|
|
typedef-name
|
|
|
|
enum-specifier
|
|
|
|
basic-type-specifier:
|
|
|
|
basic-type
|
|
|
|
basic-type basic-type-specifiers
|
|
|
|
basic-type:\fB
|
|
|
|
char
|
|
|
|
short
|
|
|
|
int
|
|
|
|
long
|
|
|
|
unsigned
|
|
|
|
float
|
|
|
|
double
|
|
|
|
void\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
At most one of the words \fBlong\fR or \fBshort\fR
|
|
|
|
may be specified in conjunction with \fBint\fR;
|
|
|
|
the meaning is the same as if \fBint\fR were not mentioned.
|
|
|
|
The word \fBlong\fR may be specified in conjunction with
|
|
|
|
\fBfloat\fR;
|
|
|
|
the meaning is the same as \fBdouble\fR.
|
|
|
|
The word \fBunsigned\fR may be specified alone, or
|
|
|
|
in conjunction with \fBint\fR or any of its short
|
|
|
|
or long varieties, or with \fBchar\fR.
|
|
|
|
.PP
|
|
|
|
Otherwise, at most on type-specifier may be
|
|
|
|
given in a declaration.
|
|
|
|
In particular, adjectival use of \fBlong\fR,
|
|
|
|
\fBshort\fR, or \fBunsigned\fR is not permitted
|
|
|
|
with \fBtypedef\fR names.
|
|
|
|
If the type-specifier is missing from a declaration,
|
|
|
|
it is taken to be \fBint\fR.
|
|
|
|
.PP
|
|
|
|
Specifiers for structures, unions, and enumerations are discussed in
|
|
|
|
``Structure, Union, and Enumeration Declarations.''
|
|
|
|
Declarations with
|
|
|
|
.B
|
|
|
|
typedef
|
|
|
|
.R
|
|
|
|
names are discussed in ``Typedef.''
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Declarators
|
|
|
|
.PP
|
|
|
|
The declarator-list appearing in a declaration
|
|
|
|
is a comma-separated sequence of declarators,
|
|
|
|
each of which may have an initializer.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIdeclarator-list:
|
|
|
|
init-declarator
|
|
|
|
init-declarator , declarator-list
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIinit-declarator:
|
|
|
|
declarator initializer\v'0.5'\s-2opt\s0\v'-0.5'\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
Initializers are discussed in ``Initialization''.
|
|
|
|
The specifiers in the declaration
|
|
|
|
indicate the type and storage class of the objects to which the
|
|
|
|
declarators refer.
|
|
|
|
Declarators have the syntax:
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIdeclarator:
|
|
|
|
identifier
|
|
|
|
( declarator )
|
|
|
|
\(** declarator
|
|
|
|
declarator ()
|
|
|
|
declarator [ constant-expression\v'0.5'\s-2opt\s0\v'-0.5' ]\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
The grouping is
|
|
|
|
the same as in expressions.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Meaning of Declarators
|
|
|
|
.PP
|
|
|
|
Each declarator is taken to be
|
|
|
|
an assertion that when a construction of
|
|
|
|
the same form as the declarator appears in an expression,
|
|
|
|
it yields an object of the indicated
|
|
|
|
type and storage class.
|
|
|
|
.PP
|
|
|
|
Each declarator contains exactly one identifier; it is this identifier that
|
|
|
|
is declared.
|
|
|
|
If an unadorned identifier appears
|
|
|
|
as a declarator, then it has the type
|
|
|
|
indicated by the specifier heading the declaration.
|
|
|
|
.PP
|
|
|
|
A declarator in parentheses is identical to the unadorned declarator,
|
|
|
|
but the binding of complex declarators may be altered by parentheses.
|
|
|
|
See the examples below.
|
|
|
|
.PP
|
|
|
|
Now imagine a declaration
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBT D1\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
where
|
|
|
|
.B
|
|
|
|
T
|
|
|
|
.R
|
|
|
|
is a type-specifier (like
|
|
|
|
\fBint\fR,
|
|
|
|
etc.)
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
D1
|
|
|
|
.R
|
|
|
|
is a declarator.
|
|
|
|
Suppose this declaration makes the identifier have type
|
|
|
|
``\|.\|.\|.\|
|
|
|
|
.B
|
|
|
|
T
|
|
|
|
.R
|
|
|
|
,''
|
|
|
|
where the ``\|.\|.\|.\|'' is empty if
|
|
|
|
.B
|
|
|
|
D1
|
|
|
|
.R
|
|
|
|
is just a plain identifier
|
|
|
|
(so that the type of
|
|
|
|
.B
|
|
|
|
x
|
|
|
|
.R
|
|
|
|
in
|
|
|
|
\fB`int x''\fR
|
|
|
|
is just
|
|
|
|
\fBint\fR).
|
|
|
|
Then if
|
|
|
|
.B
|
|
|
|
D1
|
|
|
|
.R
|
|
|
|
has the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fB\(**D\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
the type of the contained identifier is
|
|
|
|
``\|.\|.\|.\| pointer to
|
|
|
|
.B
|
|
|
|
T
|
|
|
|
.R
|
|
|
|
\&.''
|
|
|
|
.PP
|
|
|
|
If
|
|
|
|
.B
|
|
|
|
D1
|
|
|
|
.R
|
|
|
|
has the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBD\|(\|\|)\|\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
then the contained identifier has the type
|
|
|
|
``\|.\|.\|. function returning
|
|
|
|
\fBT\fR.''
|
|
|
|
.LP
|
|
|
|
If
|
|
|
|
.B
|
|
|
|
D1
|
|
|
|
.R
|
|
|
|
has the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBD\|[\|\fIconstant-expression\fB\|]\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
or
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBD\|[\|]\|\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
then the contained identifier has type
|
|
|
|
``\|.\|.\|.\| array of
|
|
|
|
\fBT\fR.''
|
|
|
|
In the first case, the constant
|
|
|
|
expression
|
|
|
|
is an expression
|
|
|
|
whose value is determinable at compile time
|
|
|
|
, whose type is
|
|
|
|
.B
|
|
|
|
int\fR,
|
|
|
|
and whose value is positive.
|
|
|
|
(Constant expressions are defined precisely in ``Constant Expressions.'')
|
|
|
|
When several ``array of'' specifications are adjacent, a multidimensional
|
|
|
|
array is created;
|
|
|
|
the constant expressions which specify the bounds
|
|
|
|
of the arrays may be missing only for the first member of the sequence.
|
|
|
|
This elision is useful when the array is external
|
|
|
|
and the actual definition, which allocates storage,
|
|
|
|
is given elsewhere.
|
|
|
|
The first constant expression may also be omitted
|
|
|
|
when the declarator is followed by initialization.
|
|
|
|
In this case the size is calculated from the number
|
|
|
|
of initial elements supplied.
|
|
|
|
.PP
|
|
|
|
An array may be constructed from one of the basic types, from a pointer,
|
|
|
|
from a structure or union,
|
|
|
|
or from another array (to generate a multidimensional array).
|
|
|
|
.PP
|
|
|
|
Not all the possibilities
|
|
|
|
allowed by the syntax above are actually
|
|
|
|
permitted.
|
|
|
|
The restrictions are as follows:
|
|
|
|
functions may not return
|
|
|
|
arrays or functions
|
|
|
|
although they may return pointers;
|
|
|
|
there are no arrays of functions although
|
|
|
|
there may be arrays of pointers to functions.
|
|
|
|
Likewise, a structure or union may not contain a function;
|
|
|
|
but it may contain a pointer to a function.
|
|
|
|
.PP
|
|
|
|
As an example, the declaration
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBint i, \(**ip, f(), \(**fip(), (\(**pfi)();\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
declares an integer
|
|
|
|
\fBi\fR,
|
|
|
|
a pointer
|
|
|
|
.B
|
|
|
|
ip
|
|
|
|
.R
|
|
|
|
to an integer,
|
|
|
|
a function
|
|
|
|
.B
|
|
|
|
f
|
|
|
|
.R
|
|
|
|
returning an integer,
|
|
|
|
a function
|
|
|
|
.B
|
|
|
|
fip
|
|
|
|
.R
|
|
|
|
returning a pointer to an integer,
|
|
|
|
and a pointer
|
|
|
|
.B
|
|
|
|
pfi
|
|
|
|
.R
|
|
|
|
to a function which
|
|
|
|
returns an integer.
|
|
|
|
It is especially useful to compare the last two.
|
|
|
|
The binding of
|
|
|
|
.B
|
|
|
|
\(**fip()
|
|
|
|
.R
|
|
|
|
is
|
|
|
|
.B
|
|
|
|
\(**(fip())\fR.
|
|
|
|
.R
|
|
|
|
The declaration suggests,
|
|
|
|
and the same construction in an expression
|
|
|
|
requires, the calling of a function
|
|
|
|
.B
|
|
|
|
fip\fR.
|
|
|
|
.R
|
|
|
|
Using indirection through the (pointer) result
|
|
|
|
to yield an integer.
|
|
|
|
In the declarator
|
|
|
|
\fB(\(**pfi)()\fR,
|
|
|
|
the extra parentheses are necessary, as they are also
|
|
|
|
in an expression, to indicate that indirection through
|
|
|
|
a pointer to a function yields a function, which is then called;
|
|
|
|
it returns an integer.
|
|
|
|
.PP
|
|
|
|
As another example,
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBfloat fa[17], \(**afp[17];\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
declares an array of
|
|
|
|
.B
|
|
|
|
float
|
|
|
|
.R
|
|
|
|
numbers and an array of
|
|
|
|
pointers to
|
|
|
|
.B
|
|
|
|
float
|
|
|
|
.R
|
|
|
|
numbers.
|
|
|
|
Finally,
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBstatic int x3d[3][5][7];\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
declares a static 3-dimensional array of integers,
|
|
|
|
with rank 3\(mu5\(mu7.
|
|
|
|
In complete detail,
|
|
|
|
.B
|
|
|
|
x3d
|
|
|
|
.R
|
|
|
|
is an array of three items;
|
|
|
|
each item is an array of five arrays;
|
|
|
|
each of the latter arrays is an array of seven
|
|
|
|
integers.
|
|
|
|
Any of the expressions
|
|
|
|
\fBx3d\fR,
|
|
|
|
\fBx3d[i]\fR,
|
|
|
|
\fBx3d[i][j]\fR,
|
|
|
|
.B
|
|
|
|
x3d[i][j][k]
|
|
|
|
.R
|
|
|
|
may reasonably appear in an expression.
|
|
|
|
The first three have type ``array''
|
|
|
|
and the last has type
|
|
|
|
.B
|
|
|
|
int\fR.
|
|
|
|
.R
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Structure and Union Declarations
|
|
|
|
.PP
|
|
|
|
A structure
|
|
|
|
is an object consisting of a sequence of named members.
|
|
|
|
Each member may have any type.
|
|
|
|
A union is an object which may, at a given time, contain any one
|
|
|
|
of several members.
|
|
|
|
Structure and union specifiers have the same form.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIstruct-or-union-specifier:
|
|
|
|
struct-or-union { struct-decl-list }
|
|
|
|
struct-or-union identifier { struct-decl-list }
|
|
|
|
struct-or-union identifier
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIstruct-or-union:\fB
|
|
|
|
struct
|
|
|
|
union\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
The
|
|
|
|
struct-decl-list
|
|
|
|
.ne 4
|
|
|
|
is a sequence of declarations for the members of the structure or union:
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIstruct-decl-list:
|
|
|
|
struct-declaration
|
|
|
|
struct-declaration struct-decl-list
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIstruct-declaration:
|
|
|
|
type-specifier struct-declarator-list ;
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIstruct-declarator-list:
|
|
|
|
struct-declarator
|
|
|
|
struct-declarator , struct-declarator-list\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
In the usual case, a struct-declarator is just a declarator
|
|
|
|
for a member of a structure or union.
|
|
|
|
A structure member may also consist of a specified number of bits.
|
|
|
|
Such a member is also called a
|
|
|
|
.I
|
|
|
|
field ;
|
|
|
|
.R
|
|
|
|
its length,
|
|
|
|
a non-negative constant expression,
|
|
|
|
is set off from the field name by a colon.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIstruct-declarator:
|
|
|
|
declarator
|
|
|
|
declarator : constant-expression
|
|
|
|
: constant-expression\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
Within a structure, the objects declared
|
|
|
|
have addresses which increase as the declarations
|
|
|
|
are read left to right.
|
|
|
|
Each nonfield member of a structure
|
|
|
|
begins on an addressing boundary appropriate
|
|
|
|
to its type;
|
|
|
|
therefore, there may
|
|
|
|
be unnamed holes in a structure.
|
|
|
|
Field members are packed into machine integers;
|
|
|
|
they do not straddle words.
|
|
|
|
A field which does not fit into the space remaining in a word
|
|
|
|
is put into the next word.
|
|
|
|
No field may be wider than a word.
|
|
|
|
.PP
|
|
|
|
Fields are assigned right to left
|
|
|
|
on the
|
|
|
|
PDP-11
|
|
|
|
and
|
|
|
|
VAX-11,
|
|
|
|
left to right on the 3B 20.
|
|
|
|
.PP
|
|
|
|
A struct-declarator with no declarator, only a colon and a width,
|
|
|
|
indicates an unnamed field useful for padding to conform
|
|
|
|
to externally-imposed layouts.
|
|
|
|
As a special case, a field with a width of 0
|
2002-10-12 14:50:50 +00:00
|
|
|
specifies alignment of the next field at an implementation dependent boundary.
|
2002-05-19 06:17:52 +00:00
|
|
|
.PP
|
|
|
|
The language does not restrict the types of things that
|
|
|
|
are declared as fields,
|
|
|
|
but implementations are not required to support any but
|
|
|
|
integer fields.
|
|
|
|
Moreover,
|
|
|
|
even
|
|
|
|
.B
|
|
|
|
int
|
|
|
|
.R
|
|
|
|
fields may be considered to be unsigned.
|
|
|
|
On the
|
|
|
|
PDP-11,
|
|
|
|
fields are not signed and have only integer values;
|
|
|
|
on the
|
|
|
|
VAX-11,
|
|
|
|
fields declared with
|
|
|
|
.B
|
|
|
|
int
|
|
|
|
.R
|
|
|
|
are treated as containing a sign.
|
|
|
|
For these reasons,
|
|
|
|
it is strongly recommended that fields be declared as
|
|
|
|
.B
|
|
|
|
unsigned\fR.
|
|
|
|
.R
|
|
|
|
In all implementations,
|
|
|
|
there are no arrays of fields,
|
|
|
|
and the address-of operator
|
|
|
|
.B
|
|
|
|
&
|
|
|
|
.R
|
|
|
|
may not be applied to them, so that there are no pointers to
|
|
|
|
fields.
|
|
|
|
.PP
|
|
|
|
A union may be thought of as a structure all of whose members
|
|
|
|
begin at offset 0 and whose size is sufficient to contain
|
|
|
|
any of its members.
|
|
|
|
At most, one of the members can be stored in a union
|
|
|
|
at any time.
|
|
|
|
.PP
|
|
|
|
A structure or union specifier of the second form, that is, one of
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBstruct \fIidentifier { struct-decl-list \fR}
|
|
|
|
\fBunion \fIidentifier { struct-decl-list \fR}
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
declares the identifier to be the
|
|
|
|
.I
|
|
|
|
structure tag
|
|
|
|
.R
|
|
|
|
(or union tag)
|
|
|
|
of the structure specified by the list.
|
|
|
|
A subsequent declaration may then use
|
|
|
|
the third form of specifier, one of
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBstruct \fIidentifier\fR
|
|
|
|
\fBunion \fIidentifier\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
Structure tags allow definition of self-referential
|
|
|
|
structures. Structure tags also
|
|
|
|
permit the long part of the declaration to be
|
|
|
|
given once and used several times.
|
|
|
|
It is illegal to declare a structure or union
|
|
|
|
which contains an instance of
|
|
|
|
itself, but a structure or union may contain a pointer to an instance of itself.
|
|
|
|
.PP
|
|
|
|
The third form of a structure or union specifier may be
|
|
|
|
used prior to a declaration which gives the complete specification
|
|
|
|
of the structure or union in situations in which the size
|
|
|
|
of the structure or union is unnecessary.
|
|
|
|
The size is unnecessary in two situations: when a
|
|
|
|
pointer to a structure or union is being declared and
|
|
|
|
when a \fBtypedef\fR name is declared to be a synonym
|
|
|
|
for a structure or union.
|
|
|
|
This, for example, allows the declaration of a pair
|
|
|
|
of structures which contain pointers to each other.
|
|
|
|
.PP
|
|
|
|
The names of members and tags do not conflict
|
|
|
|
with each other or with ordinary variables.
|
|
|
|
A particular name may not be used twice
|
|
|
|
in the same structure,
|
|
|
|
but the same name may be used in several different structures in the same scope.
|
|
|
|
.PP
|
|
|
|
A simple but important example of a structure declaration is
|
|
|
|
the following binary tree structure:
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
|
|
|
\fBstruct tnode
|
2002-05-19 06:17:52 +00:00
|
|
|
{
|
|
|
|
char tword[20];
|
|
|
|
int count;
|
|
|
|
struct tnode \(**left;
|
|
|
|
struct tnode \(**right;
|
|
|
|
};\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
which contains an array of 20 characters, an integer, and two pointers
|
|
|
|
to similar structures.
|
|
|
|
Once this declaration has been given, the
|
|
|
|
declaration
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBstruct tnode s, \(**sp;\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
declares
|
|
|
|
.B
|
|
|
|
s
|
|
|
|
.R
|
|
|
|
to be a structure of the given sort
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
sp
|
|
|
|
.R
|
|
|
|
to be a pointer to a structure
|
|
|
|
of the given sort.
|
|
|
|
With these declarations, the expression
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBsp->count\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
refers to the
|
|
|
|
.B
|
|
|
|
count
|
|
|
|
.R
|
|
|
|
field of the structure to which
|
|
|
|
.B
|
|
|
|
sp
|
|
|
|
.R
|
|
|
|
points;
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBs.left\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
refers to the left subtree pointer
|
|
|
|
of the structure
|
|
|
|
\fBs\fR;
|
|
|
|
and
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBs.right->tword[0]\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
refers to the first character of the
|
|
|
|
.B
|
|
|
|
tword
|
|
|
|
.R
|
|
|
|
member of the right subtree of
|
|
|
|
.B
|
|
|
|
s\fR.
|
|
|
|
.R
|
|
|
|
.PP
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Enumeration Declarations
|
|
|
|
.PP
|
|
|
|
Enumeration variables and constants have integral type.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIenum-specifier:\fB
|
|
|
|
enum\fI { enum-list \fR}\fB
|
|
|
|
enum \fIidentifier { enum-list \fR}\fB
|
|
|
|
enum \fIidentifier
|
|
|
|
.sp
|
|
|
|
enum-list:
|
|
|
|
enumerator
|
|
|
|
enum-list , enumerator
|
|
|
|
.sp
|
|
|
|
enumerator:
|
|
|
|
identifier
|
|
|
|
identifier = constant-expression\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
The identifiers in an enum-list are declared as constants
|
|
|
|
and may appear wherever constants are required.
|
|
|
|
If no enumerators with
|
|
|
|
.B
|
|
|
|
=
|
|
|
|
.R
|
|
|
|
appear, then the values of the
|
|
|
|
corresponding constants begin at 0 and increase by 1 as the declaration is
|
|
|
|
read from left to right.
|
|
|
|
An enumerator with
|
|
|
|
.B
|
|
|
|
=
|
|
|
|
.R
|
|
|
|
gives the associated identifier the value
|
|
|
|
indicated; subsequent identifiers continue the progression from the assigned value.
|
|
|
|
.PP
|
|
|
|
The names of enumerators in the same scope must all be distinct
|
|
|
|
from each other and from those of ordinary variables.
|
|
|
|
.PP
|
|
|
|
The role of the identifier in the enum-specifier
|
|
|
|
is entirely analogous to that of the structure tag
|
|
|
|
in a struct-specifier; it names a particular enumeration.
|
|
|
|
For example,
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS L
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBenum color { chartreuse, burgundy, claret=20, winedark };
|
|
|
|
\&...
|
2002-05-19 06:55:13 +00:00
|
|
|
enum color *cp, col;
|
2002-05-19 06:17:52 +00:00
|
|
|
\&...
|
|
|
|
col = claret;
|
|
|
|
cp = &col;
|
|
|
|
\&...
|
2002-05-19 06:55:13 +00:00
|
|
|
if (*cp == burgundy) ...\fR
|
2002-05-19 06:17:52 +00:00
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
makes
|
|
|
|
.B
|
|
|
|
color
|
|
|
|
.R
|
|
|
|
the enumeration-tag of a type describing various colors,
|
|
|
|
and then declares
|
|
|
|
.B
|
|
|
|
cp
|
|
|
|
.R
|
|
|
|
as a pointer to an object of that type,
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
col
|
|
|
|
.R
|
|
|
|
as an object of that type.
|
|
|
|
The possible values are drawn from the set {0,1,20,21}.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Initialization
|
|
|
|
.PP
|
|
|
|
A declarator may specify an initial value for the
|
|
|
|
identifier being declared.
|
|
|
|
The initializer is preceded by
|
|
|
|
.B
|
2002-10-12 14:50:50 +00:00
|
|
|
=
|
2002-05-19 06:17:52 +00:00
|
|
|
.R
|
|
|
|
and
|
|
|
|
consists of an expression or a list of values nested in braces.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIinitializer:
|
|
|
|
= expression
|
|
|
|
= { initializer-list }
|
|
|
|
= { initializer-list , }
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIinitializer-list:
|
|
|
|
expression
|
|
|
|
initializer-list , initializer-list\fR
|
|
|
|
{ \fIinitializer-list \fR}
|
|
|
|
{ \fIinitializer-list\fR , }
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
All the expressions in an initializer
|
|
|
|
for a static or external variable must be constant
|
|
|
|
expressions, which are described in ``CONSTANT EXPRESSIONS'',
|
|
|
|
or expressions which reduce to the address of a previously
|
|
|
|
declared variable, possibly offset by a constant expression.
|
|
|
|
Automatic or register variables may be initialized by arbitrary
|
|
|
|
expressions involving constants and previously declared variables and functions.
|
|
|
|
.PP
|
|
|
|
Static and external variables that are not initialized are
|
|
|
|
guaranteed to start off as zero.
|
|
|
|
Automatic and register variables that are not initialized
|
|
|
|
are guaranteed to start off as garbage.
|
|
|
|
.PP
|
|
|
|
When an initializer applies to a
|
|
|
|
.I
|
|
|
|
scalar
|
|
|
|
.R
|
|
|
|
(a pointer or an object of arithmetic type),
|
|
|
|
it consists of a single expression, perhaps in braces.
|
|
|
|
The initial value of the object is taken from
|
|
|
|
the expression; the same conversions as for assignment are performed.
|
|
|
|
.PP
|
|
|
|
When the declared variable is an
|
|
|
|
.I
|
|
|
|
aggregate
|
|
|
|
.R
|
|
|
|
(a structure or array),
|
|
|
|
the initializer consists of a brace-enclosed, comma-separated list of
|
|
|
|
initializers for the members of the aggregate
|
|
|
|
written in increasing subscript or member order.
|
|
|
|
If the aggregate contains subaggregates, this rule
|
|
|
|
applies recursively to the members of the aggregate.
|
|
|
|
If there are fewer initializers in the list than there are members of the aggregate,
|
|
|
|
then the aggregate is padded with zeros.
|
|
|
|
It is not permitted to initialize unions or automatic aggregates.
|
|
|
|
.PP
|
|
|
|
Braces may in some cases be omitted.
|
|
|
|
If the initializer begins with a left brace, then
|
|
|
|
the succeeding comma-separated list of initializers initializes
|
|
|
|
the members of the aggregate;
|
|
|
|
it is erroneous for there to be more initializers than members.
|
|
|
|
If, however, the initializer does not begin with a left brace,
|
|
|
|
then only enough elements from the list are taken to account
|
|
|
|
for the members of the aggregate; any remaining members
|
|
|
|
are left to initialize the next member of the aggregate of which
|
|
|
|
the current aggregate is a part.
|
|
|
|
.PP
|
|
|
|
A final abbreviation allows a
|
|
|
|
.B
|
|
|
|
char
|
|
|
|
.R
|
|
|
|
array to be initialized by a string.
|
|
|
|
In this case successive characters of the string
|
|
|
|
initialize the members of the array.
|
|
|
|
.PP
|
|
|
|
For example,
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBint x[] = { 1, 3, 5 };\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
declares and initializes
|
|
|
|
.B
|
|
|
|
x
|
|
|
|
.R
|
|
|
|
as a one-dimensional array which has three members, since no size was specified
|
|
|
|
and there are three initializers.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
|
|
|
\fBfloat y[4][3] =
|
2002-05-19 06:17:52 +00:00
|
|
|
{
|
|
|
|
{ 1, 3, 5 },
|
|
|
|
{ 2, 4, 6 },
|
|
|
|
{ 3, 5, 7 },
|
|
|
|
};\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
is a completely-bracketed initialization:
|
|
|
|
1, 3, and 5 initialize the first row of
|
|
|
|
the array
|
|
|
|
\fBy[0]\fR,
|
|
|
|
namely
|
|
|
|
\fBy[0][0]\fR,
|
|
|
|
\fBy[0][1]\fR,
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
y[0][2]\fR.
|
|
|
|
.R
|
|
|
|
Likewise, the next two lines initialize
|
|
|
|
.B
|
|
|
|
y[1]
|
|
|
|
.R
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
y[2]\fR.
|
|
|
|
.R
|
|
|
|
The initializer ends early and therefore
|
|
|
|
.B
|
|
|
|
y[3]
|
|
|
|
.R
|
|
|
|
is initialized with 0.
|
|
|
|
Precisely, the same effect could have been achieved by
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
|
|
|
\fBfloat y[4][3] =
|
2002-05-19 06:17:52 +00:00
|
|
|
{
|
|
|
|
1, 3, 5, 2, 4, 6, 3, 5, 7
|
|
|
|
};\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
The initializer for
|
|
|
|
.B
|
|
|
|
y
|
|
|
|
.R
|
|
|
|
begins with a left brace but that for
|
|
|
|
.B
|
|
|
|
y[0]
|
|
|
|
.R
|
|
|
|
does not;
|
|
|
|
therefore, three elements from the list are used.
|
|
|
|
Likewise, the next three are taken successively for
|
|
|
|
.B
|
|
|
|
y[1]
|
|
|
|
.R
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
y[2]\fR.
|
|
|
|
.R
|
|
|
|
Also,
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
|
|
|
\fBfloat y[4][3] =
|
2002-05-19 06:17:52 +00:00
|
|
|
{
|
|
|
|
{ 1 }, { 2 }, { 3 }, { 4 }
|
|
|
|
};\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
initializes the first column of
|
|
|
|
.B
|
|
|
|
y
|
|
|
|
.R
|
|
|
|
(regarded as a two-dimensional array)
|
|
|
|
and leaves the rest 0.
|
|
|
|
.PP
|
|
|
|
Finally,
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBchar msg[] = "Syntax error on line %s\en";\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
shows a character array whose members are initialized
|
|
|
|
with a string.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Type Names
|
|
|
|
.PP
|
|
|
|
In two contexts (to specify type conversions explicitly
|
|
|
|
by means of a cast
|
|
|
|
and as an argument of
|
|
|
|
\fBsizeof\fR),
|
|
|
|
it is desired to supply the name of a data type.
|
|
|
|
This is accomplished using a ``type name'', which in essence
|
|
|
|
is a declaration for an object of that type which omits the name of
|
|
|
|
the object.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fItype-name:
|
|
|
|
type-specifier abstract-declarator
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIabstract-declarator:
|
|
|
|
empty
|
|
|
|
( abstract-declarator )
|
|
|
|
\(** abstract-declarator
|
|
|
|
abstract-declarator ()
|
|
|
|
abstract-declarator\fR\^ [ \fIconstant-expression\v'0.5'\s-2opt\s0\v'-0.5' \fR\^]
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
To avoid ambiguity,
|
|
|
|
in the construction
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fI( abstract-declarator \fR)
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
the
|
|
|
|
abstract-declarator
|
|
|
|
is required to be nonempty.
|
|
|
|
Under this restriction,
|
|
|
|
it is possible to identify uniquely the location in the abstract-declarator
|
|
|
|
where the identifier would appear if the construction were a declarator
|
|
|
|
in a declaration.
|
|
|
|
The named type is then the same as the type of the
|
|
|
|
hypothetical identifier.
|
|
|
|
For example,
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBint
|
|
|
|
int \(**
|
|
|
|
int \(**[3]
|
|
|
|
int (\(**)[3]
|
|
|
|
int \(**()
|
|
|
|
int (\(**)()
|
|
|
|
int (\(**[3])()\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
name respectively the types ``integer,'' ``pointer to integer,''
|
|
|
|
``array of three pointers to integers,''
|
|
|
|
``pointer to an array of three integers,''
|
|
|
|
``function returning pointer to integer,''
|
|
|
|
``pointer to function returning an integer,''
|
|
|
|
and ``array of three pointers to functions returning an integer.''
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Typedef
|
|
|
|
.PP
|
|
|
|
Declarations whose ``storage class'' is
|
|
|
|
.B
|
|
|
|
typedef
|
|
|
|
.R
|
|
|
|
do not define storage but instead
|
|
|
|
define identifiers which can be used later
|
|
|
|
as if they were type keywords naming fundamental
|
|
|
|
or derived types.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fItypedef-name:\fR
|
|
|
|
\fIidentifier\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
Within the scope of a declaration involving
|
|
|
|
\fBtypedef\fR,
|
|
|
|
each identifier appearing as part of
|
|
|
|
any declarator therein becomes syntactically
|
|
|
|
equivalent to the type keyword
|
|
|
|
naming the type
|
|
|
|
associated with the identifier
|
|
|
|
in the way described in ``Meaning of Declarators.''
|
|
|
|
For example,
|
|
|
|
after
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBtypedef int MILES, \(**KLICKSP;
|
|
|
|
typedef struct { double re, im; } complex;\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
the constructions
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBMILES distance;
|
|
|
|
extern KLICKSP metricp;
|
|
|
|
complex z, \(**zp;\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.LP
|
2002-05-19 06:17:52 +00:00
|
|
|
are all legal declarations; the type of
|
|
|
|
.B
|
|
|
|
distance
|
|
|
|
.R
|
|
|
|
is
|
|
|
|
\fBint\fR,
|
|
|
|
that of
|
|
|
|
.B
|
|
|
|
metricp
|
|
|
|
.R
|
|
|
|
is ``pointer to \fBint\fR, ''
|
|
|
|
and that of
|
|
|
|
.B
|
|
|
|
z
|
|
|
|
.R
|
|
|
|
is the specified structure.
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
zp
|
|
|
|
.R
|
|
|
|
is a pointer to such a structure.
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
typedef
|
|
|
|
.R
|
|
|
|
does not introduce brand-new types, only synonyms for
|
|
|
|
types which could be specified in another way.
|
|
|
|
Thus
|
|
|
|
in the example above
|
|
|
|
.B
|
|
|
|
distance
|
|
|
|
.R
|
|
|
|
is considered to have exactly the same type as
|
|
|
|
any other
|
|
|
|
.B
|
|
|
|
int
|
|
|
|
.R
|
|
|
|
object.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
Statements
|
|
|
|
.PP
|
|
|
|
Except as indicated, statements are executed in sequence.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Expression Statement
|
|
|
|
.PP
|
|
|
|
Most statements are expression statements, which have
|
|
|
|
the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIexpression \fR;
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
Usually expression statements are assignments or function
|
|
|
|
calls.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Compound Statement or Block
|
|
|
|
.PP
|
|
|
|
So that several statements can be used where one is expected,
|
|
|
|
the compound statement (also, and equivalently, called ``block'') is provided:
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIcompound-statement:
|
|
|
|
{ declaration-list\v'0.5'\s-2opt\s0\v'-0.5' statement-list\v'0.5'\s-2opt\s0\v'-0.5' }
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIdeclaration-list:
|
|
|
|
declaration
|
|
|
|
declaration declaration-list
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIstatement-list:
|
|
|
|
statement
|
|
|
|
statement statement-list\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
If any of the identifiers
|
|
|
|
in the declaration-list were previously declared,
|
|
|
|
the outer declaration is pushed down for the duration of the block,
|
|
|
|
after which it resumes its force.
|
|
|
|
.PP
|
|
|
|
Any initializations of
|
|
|
|
.B
|
|
|
|
auto
|
|
|
|
.R
|
|
|
|
or
|
|
|
|
.B
|
|
|
|
register
|
|
|
|
.R
|
|
|
|
variables are performed each time the block is entered at the top.
|
|
|
|
It is currently possible
|
|
|
|
(but a bad practice)
|
|
|
|
to transfer into a block;
|
|
|
|
in that case the initializations are not performed.
|
|
|
|
Initializations of
|
|
|
|
.B
|
|
|
|
static
|
|
|
|
.R
|
|
|
|
variables are performed only once when the program
|
|
|
|
begins execution.
|
|
|
|
Inside a block,
|
|
|
|
.B
|
|
|
|
extern
|
|
|
|
.R
|
|
|
|
declarations do not reserve storage
|
|
|
|
so initialization is not permitted.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Conditional Statement
|
|
|
|
.PP
|
|
|
|
The two forms of the conditional statement are
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBif\fR\^ ( \fIexpression\fR\^ ) \fIstatement\fR\^
|
|
|
|
\fBif\fR\^ ( \fIexpression\fR\^ ) \fIstatement \fBelse \fIstatement\fR\^
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.PP
|
2002-05-19 06:17:52 +00:00
|
|
|
In both cases, the expression is evaluated;
|
|
|
|
and if it is nonzero, the first substatement
|
|
|
|
is executed.
|
|
|
|
In the second case, the second substatement is executed
|
|
|
|
if the expression is 0.
|
|
|
|
The ``else'' ambiguity is resolved by connecting
|
|
|
|
an
|
|
|
|
.B
|
|
|
|
else
|
|
|
|
.R
|
|
|
|
with the last encountered
|
|
|
|
\fBelse\fR-less
|
|
|
|
.B
|
|
|
|
if\fR.
|
|
|
|
.R
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
While Statement
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
while
|
|
|
|
.R
|
|
|
|
statement has the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBwhile\fR\^ ( \fIexpression\fR\^ ) \fIstatement\fR\^
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The substatement is executed repeatedly
|
|
|
|
so long as the value of the
|
|
|
|
expression remains nonzero.
|
|
|
|
The test takes place before each execution of the
|
|
|
|
statement.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Do Statement
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
do
|
|
|
|
.R
|
|
|
|
statement has the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBdo \fIstatement \fBwhile\fR\^ ( \fIexpression \fR\^) ;
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The substatement is executed repeatedly until
|
|
|
|
the value of the expression becomes 0.
|
|
|
|
The test takes place after each execution of the
|
|
|
|
statement.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
For Statement
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
for
|
|
|
|
.R
|
|
|
|
statement has the form:
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBfor\fI ( exp-1\v'0.5'\s-2opt\s0\v'-0.5' ; exp-2\v'0.5'\s-2opt\s0\v'-0.5' ; exp-3\v'0.5'\s-2opt\s0\v'-0.5' ) statement\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
.sp
|
|
|
|
Except for the behavior of \fBcontinue\fR,
|
|
|
|
this statement is equivalent to
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIexp-1 \fR;
|
|
|
|
\fBwhile\fR\^ ( \fIexp-2\ ) \fR\^
|
|
|
|
{
|
|
|
|
\fIstatement
|
|
|
|
exp-3 ;\fR
|
|
|
|
}
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
Thus the first expression specifies initialization
|
|
|
|
for the loop; the second specifies
|
|
|
|
a test, made before each iteration, such
|
|
|
|
that the loop is exited when the expression becomes
|
|
|
|
0.
|
|
|
|
The third expression often specifies an incrementing
|
|
|
|
that is performed after each iteration.
|
|
|
|
.PP
|
|
|
|
Any or all of the expressions may be dropped.
|
|
|
|
A missing
|
|
|
|
.I
|
|
|
|
exp-2
|
|
|
|
.R
|
|
|
|
makes the
|
|
|
|
implied
|
|
|
|
.B
|
|
|
|
while
|
|
|
|
.R
|
|
|
|
clause equivalent to
|
|
|
|
\fBwhile(1)\fR;
|
|
|
|
other missing expressions are simply
|
|
|
|
dropped from the expansion above.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Switch Statement
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
switch
|
|
|
|
.R
|
|
|
|
statement causes control to be transferred
|
|
|
|
to one of several statements depending on
|
|
|
|
the value of an expression.
|
|
|
|
It has the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBswitch\fR\^ ( \fIexpression\fR\^ ) \fIstatement\fR\^
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The usual arithmetic conversion is performed on the
|
|
|
|
expression, but the result must be
|
|
|
|
.B
|
|
|
|
int\fR.
|
|
|
|
.R
|
|
|
|
The statement is typically compound.
|
|
|
|
Any statement within the statement
|
|
|
|
may be labeled with one or more case prefixes
|
|
|
|
as follows:
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBcase \fIconstant-expression \fR:
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
where the constant
|
|
|
|
expression
|
|
|
|
must be
|
|
|
|
.B
|
|
|
|
int\fR.
|
|
|
|
.R
|
|
|
|
No two of the case constants in the same switch
|
|
|
|
may have the same value.
|
|
|
|
Constant expressions are precisely defined in ``CONSTANT EXPRESSIONS.''
|
|
|
|
.PP
|
|
|
|
There may also be at most one statement prefix of the
|
|
|
|
form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBdefault :\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
When the
|
|
|
|
.B
|
|
|
|
switch
|
|
|
|
.R
|
|
|
|
statement is executed, its expression
|
|
|
|
is evaluated and compared with each case constant.
|
|
|
|
If one of the case constants is
|
|
|
|
equal to the value of the expression,
|
|
|
|
control is passed to the statement
|
|
|
|
following the matched case prefix.
|
|
|
|
If no case constant matches the expression
|
|
|
|
and if there is a
|
|
|
|
\fBdefault\fR,
|
|
|
|
prefix, control
|
|
|
|
passes to the prefixed
|
|
|
|
statement.
|
|
|
|
If no case matches and if there is no
|
|
|
|
\fBdefault\fR,
|
|
|
|
then
|
|
|
|
none of the statements in the
|
|
|
|
switch is executed.
|
|
|
|
.PP
|
|
|
|
The prefixes
|
|
|
|
.B
|
|
|
|
case
|
|
|
|
.R
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
default
|
|
|
|
.R
|
|
|
|
do not alter the flow of control,
|
|
|
|
which continues unimpeded across such prefixes.
|
|
|
|
To exit from a switch, see
|
|
|
|
``Break Statement.''
|
|
|
|
.PP
|
|
|
|
Usually, the statement that is the subject of a switch is compound.
|
|
|
|
Declarations may appear at the head of this
|
|
|
|
statement,
|
|
|
|
but
|
|
|
|
initializations of automatic or register variables
|
|
|
|
are ineffective.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Break Statement
|
|
|
|
.PP
|
|
|
|
The statement
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBbreak ;\fR
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
causes termination of the smallest enclosing
|
|
|
|
\fBwhile\fR,
|
|
|
|
\fBdo\fR,
|
|
|
|
\fBfor\fR,
|
|
|
|
or
|
|
|
|
\fBswitch\fR
|
|
|
|
statement;
|
|
|
|
control passes to the
|
|
|
|
statement following the terminated statement.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Continue Statement
|
|
|
|
.PP
|
|
|
|
The statement
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBcontinue ;\fR
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
causes control to pass to the loop-continuation portion of the
|
|
|
|
smallest enclosing
|
|
|
|
\fBwhile\fR,
|
|
|
|
\fBdo\fR,
|
|
|
|
or
|
|
|
|
\fBfor\fR
|
|
|
|
statement; that is to the end of the loop.
|
|
|
|
More precisely, in each of the statements
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
.TS
|
|
|
|
lw(2i) lw(2i) lw(2i).
|
|
|
|
\fBwhile (\|.\|.\|.\|) { do { for (\|.\|.\|.\|) {\fR
|
|
|
|
\fIstatement ; statement ; statement ;\fR
|
|
|
|
\fBcontin: ; contin: ; contin: ;
|
|
|
|
} } while (...); }\fR
|
|
|
|
.TE
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
a
|
|
|
|
.B
|
|
|
|
continue
|
|
|
|
.R
|
|
|
|
is equivalent to
|
|
|
|
.B
|
|
|
|
goto\ contin\fR.
|
|
|
|
.R
|
|
|
|
(Following the
|
|
|
|
.B
|
|
|
|
contin:
|
|
|
|
.R
|
|
|
|
is a null statement, see ``Null Statement''.)
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Return Statement
|
|
|
|
.PP
|
|
|
|
A function returns to its caller by means of
|
|
|
|
the
|
|
|
|
.B
|
|
|
|
return
|
|
|
|
.R
|
|
|
|
statement which has one of the
|
|
|
|
forms
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBreturn ;
|
|
|
|
return \fIexpression \fR;
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
In the first case, the returned value is undefined.
|
|
|
|
In the second case, the value of the expression
|
|
|
|
is returned to the caller
|
|
|
|
of the function.
|
|
|
|
If required, the expression is converted,
|
|
|
|
as if by assignment, to the type of
|
|
|
|
function in which it appears.
|
|
|
|
Flowing off the end of a function is
|
|
|
|
equivalent to a return with no returned value.
|
|
|
|
The expression may be parenthesized.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Goto Statement
|
|
|
|
.PP
|
|
|
|
Control may be transferred unconditionally by means of
|
|
|
|
the statement
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBgoto \fIidentifier \fR;
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The identifier must be a label
|
|
|
|
(see ``Labeled Statement'')
|
|
|
|
located in the current function.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Labeled Statement
|
|
|
|
.PP
|
|
|
|
Any statement may be preceded by
|
|
|
|
label prefixes of the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIidentifier \fR:
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
which serve to declare the identifier
|
|
|
|
as a label.
|
|
|
|
The only use of a label is as a target of a
|
|
|
|
.B
|
|
|
|
goto\fR.
|
|
|
|
.R
|
|
|
|
The scope of a label is the current function,
|
|
|
|
excluding any subblocks in which the same identifier has been redeclared.
|
|
|
|
See ``SCOPE RULES.''
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Null Statement
|
|
|
|
.PP
|
|
|
|
The null statement has the form
|
|
|
|
.DS
|
|
|
|
\fB;\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
A null statement is useful to carry a label just before the
|
|
|
|
.B
|
|
|
|
}
|
|
|
|
.R
|
|
|
|
of a compound statement or to supply a null
|
|
|
|
body to a looping statement such as
|
|
|
|
.B
|
|
|
|
while\fR.
|
|
|
|
.R
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
External Definitions
|
|
|
|
.PP
|
|
|
|
A C program consists of a sequence of external definitions.
|
|
|
|
An external definition declares an identifier to
|
|
|
|
have storage class
|
|
|
|
.B
|
|
|
|
extern
|
|
|
|
.R
|
|
|
|
(by default)
|
|
|
|
or perhaps
|
|
|
|
\fBstatic\fR,
|
|
|
|
and
|
|
|
|
a specified type.
|
|
|
|
The type-specifier (see ``Type Specifiers'' in
|
|
|
|
``DECLARATIONS'') may also be empty, in which
|
|
|
|
case the type is taken to be
|
|
|
|
.B
|
|
|
|
int\fR.
|
|
|
|
.R
|
|
|
|
The scope of external definitions persists to the end
|
|
|
|
of the file in which they are declared just as the effect
|
|
|
|
of declarations persists to the end of a block.
|
|
|
|
The syntax of external definitions is the same
|
|
|
|
as that of all declarations except that
|
|
|
|
only at this level may the code for functions be given.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
External Function Definitions
|
|
|
|
.PP
|
|
|
|
Function definitions have the form
|
|
|
|
.DS
|
|
|
|
\fIfunction-definition:
|
|
|
|
decl-specifiers\v'0.5'\s-2opt\s0\v'-0.5' function-declarator function-body\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The only sc-specifiers
|
|
|
|
allowed
|
|
|
|
among the decl-specifiers
|
|
|
|
are
|
|
|
|
.B
|
|
|
|
extern
|
|
|
|
.R
|
|
|
|
or
|
|
|
|
\fBstatic\fR;
|
2002-10-12 14:50:50 +00:00
|
|
|
see ``Scope of Externals'' in
|
2002-05-19 06:17:52 +00:00
|
|
|
``SCOPE RULES'' for the distinction between them.
|
|
|
|
A function declarator is similar to a declarator
|
|
|
|
for a ``function returning .\|.\|.\|'' except that
|
|
|
|
it lists the formal parameters of
|
|
|
|
the function being defined.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIfunction-declarator:
|
|
|
|
declarator ( parameter-list\v'0.5'\s-2opt\s0\v'-0.5' )
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIparameter-list:
|
|
|
|
identifier
|
|
|
|
identifier , parameter-list\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The function-body
|
|
|
|
has the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIfunction-body:
|
|
|
|
declaration-list\v'0.5'\s-2opt\s0\v'-0.5' compound-statement\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The identifiers in the parameter list, and only those identifiers,
|
|
|
|
may be declared in the declaration list.
|
|
|
|
Any identifiers whose type is not given are taken to be
|
|
|
|
.B
|
|
|
|
int\fR.
|
|
|
|
.R
|
|
|
|
The only storage class which may be specified is
|
|
|
|
\fBregister\fR;
|
|
|
|
if it is specified, the corresponding actual parameter
|
|
|
|
will be copied, if possible, into a register
|
|
|
|
at the outset of the function.
|
|
|
|
.PP
|
|
|
|
A simple example of a complete function definition is
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBint max(a, b, c)
|
|
|
|
int a, b, c;
|
|
|
|
{
|
|
|
|
int m;
|
|
|
|
.sp
|
|
|
|
m = (a > b) ? a : b;
|
|
|
|
return((m > c) ? m : c);
|
|
|
|
}\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
Here
|
|
|
|
.B
|
|
|
|
int
|
|
|
|
.R
|
|
|
|
is the type-specifier;
|
|
|
|
.B
|
|
|
|
max(a,\ b,\ c)
|
|
|
|
.R
|
|
|
|
is the function-declarator;
|
|
|
|
.B
|
|
|
|
int\ a,\ b,\ c;
|
|
|
|
.R
|
|
|
|
is the declaration-list for
|
|
|
|
the formal
|
|
|
|
parameters;
|
|
|
|
\fB{\ ...\ }\fR
|
|
|
|
is the
|
|
|
|
block giving the code for the statement.
|
|
|
|
.PP
|
|
|
|
The C program converts all
|
|
|
|
.B
|
|
|
|
float
|
|
|
|
.R
|
|
|
|
actual parameters
|
|
|
|
to
|
|
|
|
\fBdouble\fR,
|
|
|
|
so formal parameters declared
|
|
|
|
.B
|
|
|
|
float
|
|
|
|
.R
|
|
|
|
have their declaration adjusted to read
|
|
|
|
.B
|
|
|
|
double\fR.
|
|
|
|
.R
|
|
|
|
All \fBchar\fR and \fBshort\fR formal parameter
|
|
|
|
declarations are similarly adjusted
|
|
|
|
to read \fBint\fR.
|
|
|
|
Also, since a reference to an array in any context
|
|
|
|
(in particular as an actual parameter)
|
|
|
|
is taken to mean
|
|
|
|
a pointer to the first element of the array,
|
|
|
|
declarations of formal parameters declared ``array of .\|.\|.\|''
|
|
|
|
are adjusted to read ``pointer to .\|.\|.\|.''
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
External Data Definitions
|
|
|
|
.PP
|
|
|
|
An external data definition has the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIdata-definition:
|
|
|
|
declaration\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The storage class of such data may be
|
|
|
|
.B
|
|
|
|
extern
|
|
|
|
.R
|
|
|
|
(which is the default)
|
|
|
|
or
|
|
|
|
.B
|
2002-10-12 14:50:50 +00:00
|
|
|
static
|
2002-05-19 06:17:52 +00:00
|
|
|
.R
|
|
|
|
but not
|
|
|
|
.B
|
|
|
|
auto
|
|
|
|
.R
|
|
|
|
or
|
|
|
|
\fBregister\fR.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
Scope Rules
|
|
|
|
.PP
|
|
|
|
A C program need not all
|
|
|
|
be compiled at the same time. The source text of the
|
|
|
|
program
|
|
|
|
may be kept in several files, and precompiled
|
|
|
|
routines may be loaded from
|
|
|
|
libraries.
|
|
|
|
Communication among the functions of a program
|
|
|
|
may be carried out both through explicit calls
|
|
|
|
and through manipulation of external data.
|
|
|
|
.PP
|
|
|
|
Therefore, there are two kinds of scopes to consider:
|
|
|
|
first, what may be called the
|
|
|
|
.UL lexical
|
|
|
|
.UL scope
|
|
|
|
of an identifier, which is essentially the
|
|
|
|
region of a program during which it may
|
|
|
|
be used without drawing ``undefined identifier''
|
|
|
|
diagnostics;
|
|
|
|
and second, the scope
|
|
|
|
associated with external identifiers,
|
|
|
|
which is characterized by the rule
|
|
|
|
that references to the same external
|
|
|
|
identifier are references to the same object.
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Lexical Scope
|
|
|
|
.PP
|
|
|
|
The lexical scope of identifiers declared in external definitions
|
|
|
|
persists from the definition through
|
|
|
|
the end of the source file
|
|
|
|
in which they appear.
|
|
|
|
The lexical scope of identifiers which are formal parameters
|
|
|
|
persists through the function with which they are
|
|
|
|
associated.
|
|
|
|
The lexical scope of identifiers declared at the head of a block
|
|
|
|
persists until the end of the block.
|
|
|
|
The lexical scope of labels is the whole of the
|
|
|
|
function in which they appear.
|
|
|
|
.PP
|
|
|
|
In all cases, however,
|
|
|
|
if an identifier is explicitly declared at the head of a block,
|
|
|
|
including the block constituting a function,
|
|
|
|
any declaration of that identifier outside the block
|
|
|
|
is suspended until the end of the block.
|
|
|
|
.PP
|
|
|
|
Remember also (see ``Structure, Union, and Enumeration Declarations'' in
|
|
|
|
``DECLARATIONS'') that tags, identifiers associated with
|
|
|
|
ordinary variables,
|
|
|
|
and identities associated with structure and union members
|
|
|
|
form three disjoint classes
|
|
|
|
which do not conflict.
|
|
|
|
Members and tags follow the same scope rules
|
|
|
|
as other identifiers.
|
|
|
|
The \fBenum\fR constants are in the same
|
|
|
|
class as ordinary variables and follow the same scope rules.
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
typedef
|
|
|
|
.R
|
|
|
|
names are in the same class as ordinary identifiers.
|
|
|
|
They may be redeclared in inner blocks, but an explicit
|
|
|
|
type must be given in the inner declaration:
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBtypedef float distance;
|
|
|
|
\&...
|
|
|
|
{
|
|
|
|
auto int distance;
|
|
|
|
...\fR
|
|
|
|
}
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
int
|
|
|
|
.R
|
|
|
|
must be present in the second declaration,
|
|
|
|
or it would be taken to be
|
|
|
|
a declaration with no declarators and type
|
|
|
|
.B
|
|
|
|
distance\fR.
|
|
|
|
.R
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Scope of Externals
|
|
|
|
.PP
|
|
|
|
If a function refers to an identifier declared to be
|
|
|
|
\fBextern\fR,
|
|
|
|
then somewhere among the files or libraries
|
|
|
|
constituting the complete program
|
|
|
|
there must be at least one external definition
|
|
|
|
for the identifier.
|
|
|
|
All functions in a given program which refer to the same
|
|
|
|
external identifier refer to the same object,
|
|
|
|
so care must be taken that the type and size
|
|
|
|
specified in the definition
|
|
|
|
are compatible with those specified
|
|
|
|
by each function which references the data.
|
|
|
|
.PP
|
|
|
|
It is illegal to explicitly initialize any external
|
|
|
|
identifier more than once in the set of files and libraries
|
|
|
|
comprising a multi-file program.
|
|
|
|
It is legal to have more than one data definition
|
|
|
|
for any external non-function identifier;
|
|
|
|
explicit use of \fBextern\fR does not
|
|
|
|
change the meaning of an external declaration.
|
|
|
|
.PP
|
|
|
|
In restricted environments, the use of the \fBextern\fR
|
|
|
|
storage class takes on an additional meaning.
|
|
|
|
In these environments, the explicit appearance of the
|
|
|
|
\fBextern\fR keyword in external data declarations of
|
|
|
|
identities without initialization indicates that
|
|
|
|
the storage for the identifiers is allocated elsewhere,
|
|
|
|
either in this file or another file.
|
|
|
|
It is required that there be exactly one definition of
|
|
|
|
each external identifier (without \fBextern\fR)
|
|
|
|
in the set of files and libraries
|
|
|
|
comprising a mult-file program.
|
|
|
|
.PP
|
|
|
|
Identifiers declared
|
|
|
|
.B
|
|
|
|
static
|
|
|
|
.R
|
|
|
|
at the top level in external definitions
|
|
|
|
are not visible in other files.
|
|
|
|
Functions may be declared
|
|
|
|
.B
|
|
|
|
static\fR.
|
|
|
|
.R
|
|
|
|
.nr Hu 1
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
Compiler Control Lines
|
|
|
|
.PP
|
|
|
|
The C compiler contains a preprocessor capable
|
|
|
|
of macro substitution, conditional compilation,
|
|
|
|
and inclusion of named files.
|
|
|
|
Lines beginning with
|
|
|
|
.B
|
|
|
|
#
|
|
|
|
.R
|
|
|
|
communicate
|
|
|
|
with this preprocessor.
|
|
|
|
There may be any number of blanks and horizontal tabs
|
|
|
|
between the \fB#\fR and the directive.
|
|
|
|
These lines have syntax independent of the rest of the language;
|
|
|
|
they may appear anywhere and have effect which lasts (independent of
|
|
|
|
scope) until the end of the source program file.
|
|
|
|
.nr Hu 1
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Token Replacement
|
|
|
|
.PP
|
|
|
|
A compiler-control line of the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fB#define \fIidentifier token-string\v'0.5'\s-2opt\s0\v'-0.5'\fR
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
causes the preprocessor to replace subsequent instances
|
|
|
|
of the identifier with the given string of tokens.
|
|
|
|
Semicolons in or at the end of the token-string are part of that string.
|
|
|
|
A line of the form
|
|
|
|
.DS
|
|
|
|
\fB#define \fIidentifier(identifier, ... )token-string\v'0.5'\s-2opt\s0\v'-0.5'\fR
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
where there is no space between the first identifier
|
|
|
|
and the
|
|
|
|
\fB(\fR,
|
|
|
|
is a macro definition with arguments.
|
|
|
|
There may be zero or more formal parameters.
|
|
|
|
Subsequent instances of the first identifier followed
|
|
|
|
by a
|
|
|
|
\fB(\fR,
|
|
|
|
a sequence of tokens delimited by commas, and a
|
|
|
|
\fB)\fR
|
|
|
|
are replaced
|
|
|
|
by the token string in the definition.
|
|
|
|
Each occurrence of an identifier mentioned in the formal parameter list
|
|
|
|
of the definition is replaced by the corresponding token string from the call.
|
|
|
|
The actual arguments in the call are token strings separated by commas;
|
|
|
|
however, commas in quoted strings or protected by
|
|
|
|
parentheses do not separate arguments.
|
|
|
|
The number of formal and actual parameters must be the same.
|
|
|
|
Strings and character constants in the token-string are scanned
|
|
|
|
for formal parameters, but
|
|
|
|
strings and character constants in the rest of the program are
|
|
|
|
not scanned for defined identifiers
|
|
|
|
to replacement.
|
|
|
|
.PP
|
|
|
|
In both forms the replacement string is rescanned for more
|
|
|
|
defined identifiers.
|
|
|
|
In both forms
|
|
|
|
a long definition may be continued on another line
|
|
|
|
by writing
|
|
|
|
.B
|
|
|
|
\e
|
|
|
|
.R
|
|
|
|
at the end of the line to be continued.
|
|
|
|
.PP
|
|
|
|
This facility is most valuable for definition of ``manifest constants,''
|
|
|
|
as in
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fB#define TABSIZE 100
|
|
|
|
.sp
|
|
|
|
int table\|[\|TABSIZE\|]\|;\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
A control line of the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fB#undef \fIidentifier\fR
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
causes the
|
|
|
|
identifier's preprocessor definition (if any) to be forgotten.
|
|
|
|
.PP
|
|
|
|
If a \fB#define\fRd identifier is the subject of a subsequent
|
|
|
|
\fB#define\fR with no intervening \fB#undef\fR, then
|
|
|
|
the two token-strings are compared textually.
|
|
|
|
If the two token-strings are not identical
|
|
|
|
(all white space is considered as equivalent), then
|
|
|
|
the identifier is considered to be redefined.
|
|
|
|
.nr Hu 1
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
File Inclusion
|
|
|
|
.PP
|
|
|
|
A compiler control line of
|
|
|
|
the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fB#include\fI "filename\|\fR"
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
causes the replacement of that
|
|
|
|
line by the entire contents of the file
|
|
|
|
.I
|
|
|
|
filename\fR.
|
|
|
|
.R
|
|
|
|
The named file is searched for first in the directory
|
|
|
|
of the file containing the \fB#include\fR,
|
|
|
|
and then in a sequence of specified or standard places.
|
|
|
|
Alternatively, a control line of the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fB#include\fI <filename\|\fR>
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
searches only the specified or standard places
|
|
|
|
and not the directory of the \fB#include\fR.
|
|
|
|
(How the places are specified is not part of the language.)
|
|
|
|
.PP
|
|
|
|
\fB#include\fRs
|
|
|
|
may be nested.
|
|
|
|
.nr Hu 1
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Conditional Compilation
|
|
|
|
.PP
|
|
|
|
A compiler control line of the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fB#if \fIrestricted-constant-expression\fR
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
checks whether the restricted-constant expression evaluates to nonzero.
|
|
|
|
(Constant expressions are discussed in ``CONSTANT EXPRESSIONS'';
|
|
|
|
the following additional restrictions apply here:
|
|
|
|
the constant expression may not contain
|
|
|
|
.B
|
|
|
|
sizeof
|
|
|
|
.R
|
|
|
|
casts, or an enumeration constant.)
|
|
|
|
.PP
|
|
|
|
A restricted constant expression may also contain the
|
|
|
|
additional unary expression
|
|
|
|
.PP
|
|
|
|
\fBdefined \fIidentifier\fR
|
|
|
|
.LP
|
|
|
|
or
|
|
|
|
.PP
|
|
|
|
\fBdefined( \fIidentifier )\fR
|
|
|
|
.LP
|
|
|
|
which evaluates to one if the identifier is currently
|
|
|
|
defined in the preprocessor and zero if it is not.
|
|
|
|
.PP
|
|
|
|
All currently defined identifiers in restricted-constant-expressions
|
|
|
|
are replaced by their token-strings (except those identifiers
|
|
|
|
modified by \fBdefined\fR) just as in normal text.
|
|
|
|
The restricted constant expression will be evaluated only
|
|
|
|
after all expressions have finished.
|
|
|
|
During this evaluation, all undefined (to the procedure)
|
|
|
|
identifiers evaluate to zero.
|
|
|
|
.PP
|
|
|
|
A control line of the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fB#ifdef \fIidentifier\fR
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
checks whether the identifier is currently defined
|
|
|
|
in the preprocessor; i.e., whether it has been the
|
|
|
|
subject of a
|
|
|
|
.B
|
|
|
|
#define
|
|
|
|
.R
|
|
|
|
control line.
|
|
|
|
It is equivalent to \fB#ifdef(\fIidentifier\fB)\fR.
|
|
|
|
A control line of the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fB#ifndef \fIidentifier\fR
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
checks whether the identifier is currently undefined
|
|
|
|
in the preprocessor.
|
|
|
|
It is equivalent to
|
|
|
|
.DS
|
|
|
|
\fB#if !\|defined(\fIidentifier\fB)\fR.
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
All three forms are followed by an arbitrary number of lines,
|
|
|
|
possibly containing a control line
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fB#else\fR
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
and then by a control line
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fB#endif\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
If the checked condition is true,
|
|
|
|
then any lines
|
|
|
|
between
|
|
|
|
.B
|
|
|
|
#else
|
|
|
|
.R
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
#endif
|
|
|
|
.R
|
|
|
|
are ignored.
|
|
|
|
If the checked condition is false, then any lines between
|
|
|
|
the test and a
|
|
|
|
.B
|
|
|
|
#else
|
|
|
|
.R
|
|
|
|
or, lacking a
|
|
|
|
\fB#else\fR,
|
|
|
|
the
|
|
|
|
.B
|
2002-10-12 14:50:50 +00:00
|
|
|
#endif
|
2002-05-19 06:17:52 +00:00
|
|
|
.R
|
|
|
|
are ignored.
|
|
|
|
.PP
|
|
|
|
These constructions may be nested.
|
|
|
|
.nr Hu 1
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Line Control
|
|
|
|
.PP
|
|
|
|
For the benefit of other preprocessors which generate C programs,
|
|
|
|
a line of the form
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fB#line \fIconstant "filename\fR"
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
causes the compiler to believe, for purposes of error
|
|
|
|
diagnostics,
|
|
|
|
that the line number of the next source line is given by the constant and the current input
|
|
|
|
file is named by "\fIfilename\fR".
|
|
|
|
If "\fIfilename\fR" is absent, the remembered file name does not change.
|
|
|
|
.nr Hu 1
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
Implicit Declarations
|
|
|
|
.PP
|
|
|
|
It is not always necessary to specify
|
|
|
|
both the storage class and the type
|
|
|
|
of identifiers in a declaration.
|
|
|
|
The storage class is supplied by
|
|
|
|
the context in external definitions
|
|
|
|
and in declarations of formal parameters
|
|
|
|
and structure members.
|
|
|
|
In a declaration inside a function,
|
|
|
|
if a storage class but no type
|
|
|
|
is given, the identifier is assumed
|
|
|
|
to be
|
|
|
|
\fBint\fR;
|
|
|
|
if a type but no storage class is indicated,
|
|
|
|
the identifier is assumed to
|
|
|
|
be
|
|
|
|
.B
|
|
|
|
auto\fR.
|
|
|
|
.R
|
|
|
|
An exception to the latter rule is made for
|
|
|
|
functions because
|
|
|
|
.B
|
|
|
|
auto
|
|
|
|
.R
|
|
|
|
functions do not exist.
|
|
|
|
If the type of an identifier is ``function returning .\|.\|.\|,''
|
|
|
|
it is implicitly declared to be
|
|
|
|
.B
|
|
|
|
extern\fR.
|
|
|
|
.R
|
|
|
|
.PP
|
|
|
|
In an expression, an identifier
|
|
|
|
followed by
|
|
|
|
.B
|
|
|
|
(
|
|
|
|
.R
|
|
|
|
and not already declared
|
|
|
|
is contextually
|
|
|
|
declared to be ``function returning
|
|
|
|
.B
|
|
|
|
int\fR.''
|
|
|
|
.nr Hu 1
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
Types Revisited
|
|
|
|
.PP
|
|
|
|
This part summarizes the operations
|
|
|
|
which can be performed on objects of certain types.
|
|
|
|
.nr Hu 1
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Structures and Unions
|
|
|
|
.PP
|
|
|
|
Structures and unions may be assigned, passed as arguments to functions,
|
|
|
|
and returned by functions.
|
|
|
|
Other plausible operators, such as equality comparison
|
|
|
|
and structure casts,
|
|
|
|
are not implemented.
|
|
|
|
.PP
|
|
|
|
In a reference
|
|
|
|
to a structure or union member, the
|
|
|
|
name on the right
|
|
|
|
of the \fB->\fR or the \fB.\fR
|
|
|
|
must specify a member of the aggregate
|
|
|
|
named or pointed to by the expression
|
|
|
|
on the left.
|
|
|
|
In general, a member of a union may not be inspected
|
|
|
|
unless the value of the union has been assigned using that same member.
|
|
|
|
However, one special guarantee is made by the language in order
|
|
|
|
to simplify the use of unions:
|
|
|
|
if a union contains several structures that share a common initial sequence
|
|
|
|
and if the union currently contains one of these structures,
|
|
|
|
it is permitted to inspect the common initial part of any of
|
|
|
|
the contained structures.
|
|
|
|
For example, the following is a legal fragment:
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
|
|
|
\fBunion
|
2002-05-19 06:17:52 +00:00
|
|
|
{
|
2002-10-12 14:50:50 +00:00
|
|
|
struct
|
2002-05-19 06:17:52 +00:00
|
|
|
{
|
|
|
|
int type;
|
|
|
|
} n;
|
2002-10-12 14:50:50 +00:00
|
|
|
struct
|
2002-05-19 06:17:52 +00:00
|
|
|
{
|
|
|
|
int type;
|
|
|
|
int intnode;
|
|
|
|
} ni;
|
2002-10-12 14:50:50 +00:00
|
|
|
struct
|
2002-05-19 06:17:52 +00:00
|
|
|
{
|
|
|
|
int type;
|
|
|
|
float floatnode;
|
|
|
|
} nf;
|
|
|
|
} u;
|
|
|
|
\&...
|
|
|
|
u.nf.type = FLOAT;
|
|
|
|
u.nf.floatnode = 3.14;
|
|
|
|
\&...
|
|
|
|
if (u.n.type == FLOAT)
|
|
|
|
... sin(u.nf.floatnode) ...\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
.nr Hu 1
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Functions
|
|
|
|
.PP
|
|
|
|
There are only two things that
|
|
|
|
can be done with a function \fBm\fR,
|
|
|
|
call it or take its address.
|
|
|
|
If the name of a function appears in an
|
|
|
|
expression not in the function-name position of a call,
|
|
|
|
a pointer to the function is generated.
|
|
|
|
Thus, to pass one function to another, one
|
|
|
|
might say
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBint f();
|
|
|
|
\&...
|
|
|
|
g(f);\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
.ne 8
|
|
|
|
Then the definition of
|
|
|
|
.B
|
|
|
|
g
|
|
|
|
.R
|
|
|
|
might read
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBg(funcp)
|
|
|
|
int (\(**funcp)();
|
|
|
|
{
|
|
|
|
...
|
|
|
|
(\(**funcp)();
|
|
|
|
...
|
|
|
|
}\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
Notice that
|
|
|
|
.B
|
|
|
|
f
|
|
|
|
.R
|
|
|
|
must be declared
|
|
|
|
explicitly in the calling routine since its appearance
|
|
|
|
in
|
|
|
|
.B
|
|
|
|
g(f)
|
|
|
|
.R
|
|
|
|
was not followed by
|
|
|
|
.B
|
|
|
|
(.
|
|
|
|
.R
|
|
|
|
.nr Hu 1
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Arrays, Pointers, and Subscripting
|
|
|
|
.PP
|
|
|
|
Every time an identifier of array type appears
|
|
|
|
in an expression, it is converted into a pointer
|
|
|
|
to the first member of the array.
|
|
|
|
Because of this conversion, arrays are not
|
|
|
|
lvalues.
|
|
|
|
By definition, the subscript operator
|
|
|
|
.B
|
|
|
|
[]
|
|
|
|
.R
|
|
|
|
is interpreted
|
|
|
|
in such a way that
|
|
|
|
.B
|
|
|
|
E1[E2]
|
|
|
|
.R
|
|
|
|
is identical to
|
|
|
|
.B
|
|
|
|
\(**((E1)\(plE2))\fR.
|
|
|
|
.R
|
|
|
|
Because of the conversion rules
|
|
|
|
which apply to
|
|
|
|
\fB\(pl\fR,
|
|
|
|
if
|
|
|
|
.B
|
|
|
|
E1
|
|
|
|
.R
|
|
|
|
is an array and
|
|
|
|
.B
|
|
|
|
E2
|
|
|
|
.R
|
|
|
|
an integer,
|
|
|
|
then
|
|
|
|
.B
|
|
|
|
E1[E2]
|
|
|
|
.R
|
|
|
|
refers to the
|
|
|
|
.B
|
|
|
|
E2-th
|
|
|
|
.R
|
|
|
|
member of
|
|
|
|
.B
|
|
|
|
E1\fR.
|
|
|
|
.R
|
|
|
|
Therefore,
|
|
|
|
despite its asymmetric
|
|
|
|
appearance, subscripting is a commutative operation.
|
|
|
|
.PP
|
|
|
|
A consistent rule is followed in the case of
|
|
|
|
multidimensional arrays.
|
|
|
|
If
|
|
|
|
.B
|
|
|
|
E
|
|
|
|
.R
|
|
|
|
is an
|
|
|
|
\fIn\fR-dimensional
|
|
|
|
array
|
|
|
|
of rank
|
|
|
|
i\(muj\(mu...\(muk,
|
|
|
|
then
|
|
|
|
.B
|
|
|
|
E
|
|
|
|
.R
|
|
|
|
appearing in an expression is converted to
|
|
|
|
a pointer to an (n-1)-dimensional
|
|
|
|
array with rank
|
|
|
|
j\(mu...\(muk.
|
|
|
|
If the
|
|
|
|
.B
|
|
|
|
\(**
|
|
|
|
.R
|
|
|
|
operator, either explicitly
|
|
|
|
or implicitly as a result of subscripting,
|
|
|
|
is applied to this pointer,
|
|
|
|
the result is the pointed-to (n-1)-dimensional array,
|
|
|
|
which itself is immediately converted into a pointer.
|
|
|
|
.PP
|
|
|
|
For example, consider
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBint x[3][5];\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
Here
|
|
|
|
.B
|
|
|
|
x
|
|
|
|
.R
|
|
|
|
is a 3\(mu5 array of integers.
|
|
|
|
When
|
|
|
|
.B
|
|
|
|
x
|
|
|
|
.R
|
|
|
|
appears in an expression, it is converted
|
|
|
|
to a pointer to (the first of three) 5-membered arrays of integers.
|
|
|
|
In the expression
|
|
|
|
\fBx[i]\fR,
|
|
|
|
which is equivalent to
|
|
|
|
\fB\(**(x\(pli)\fR,
|
|
|
|
.B
|
|
|
|
x
|
|
|
|
.R
|
|
|
|
is first converted to a pointer as described;
|
|
|
|
then
|
|
|
|
.B
|
|
|
|
i
|
|
|
|
.R
|
|
|
|
is converted to the type of
|
|
|
|
\fBx\fR,
|
|
|
|
which involves multiplying
|
|
|
|
.B
|
|
|
|
i
|
|
|
|
.R
|
|
|
|
by the
|
|
|
|
length the object to which the pointer points,
|
|
|
|
namely 5-integer objects.
|
|
|
|
The results are added and indirection applied to
|
|
|
|
yield an array (of five integers) which in turn is converted to
|
|
|
|
a pointer to the first of the integers.
|
|
|
|
If there is another subscript, the same argument applies
|
|
|
|
again; this time the result is an integer.
|
|
|
|
.PP
|
|
|
|
Arrays in C are stored
|
|
|
|
row-wise (last subscript varies fastest)
|
|
|
|
and the first subscript in the declaration helps determine
|
|
|
|
the amount of storage consumed by an array.
|
|
|
|
Arrays play no other part in subscript calculations.
|
|
|
|
.nr Hu 1
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Explicit Pointer Conversions
|
|
|
|
.PP
|
|
|
|
Certain conversions involving pointers are permitted
|
|
|
|
but have implementation-dependent aspects.
|
|
|
|
They are all specified by means of an explicit type-conversion
|
|
|
|
operator, see ``Unary Operators'' under``EXPRESSIONS'' and
|
|
|
|
``Type Names''under ``DECLARATIONS.''
|
|
|
|
.PP
|
|
|
|
A pointer may be converted to any of the integral types large
|
|
|
|
enough to hold it.
|
|
|
|
Whether an
|
|
|
|
.B
|
|
|
|
int
|
|
|
|
.R
|
|
|
|
or
|
|
|
|
.B
|
|
|
|
long
|
|
|
|
.R
|
|
|
|
is required is machine dependent.
|
|
|
|
The mapping function is also machine dependent but is intended
|
|
|
|
to be unsurprising to those who know the addressing structure
|
|
|
|
of the machine.
|
|
|
|
Details for some particular machines are given below.
|
|
|
|
.PP
|
|
|
|
An object of integral type may be explicitly converted to a pointer.
|
|
|
|
The mapping always carries an integer converted from a pointer back to the same pointer
|
|
|
|
but is otherwise machine dependent.
|
|
|
|
.PP
|
|
|
|
A pointer to one type may be converted to a pointer to another type.
|
|
|
|
The resulting pointer may cause addressing exceptions
|
|
|
|
upon use if
|
|
|
|
the subject pointer does not refer to an object suitably aligned in storage.
|
|
|
|
It is guaranteed that
|
|
|
|
a pointer to an object of a given size may be converted to a pointer to an object
|
|
|
|
of a smaller size
|
|
|
|
and back again without change.
|
|
|
|
.PP
|
|
|
|
For example,
|
|
|
|
a storage-allocation routine
|
|
|
|
might accept a size (in bytes)
|
|
|
|
of an object to allocate, and return a
|
|
|
|
.B
|
|
|
|
char
|
|
|
|
.R
|
|
|
|
pointer;
|
|
|
|
it might be used in this way.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fBextern char \(**malloc();
|
|
|
|
double \(**dp;
|
|
|
|
.sp
|
|
|
|
dp = (double \(**) malloc(sizeof(double));
|
|
|
|
\(**dp = 22.0 / 7.0;\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
alloc
|
|
|
|
.R
|
|
|
|
must ensure (in a machine-dependent way)
|
|
|
|
that its return value is suitable for conversion to a pointer to
|
|
|
|
\fBdouble\fR;
|
|
|
|
then the
|
|
|
|
.I
|
|
|
|
use
|
|
|
|
.R
|
|
|
|
of the function is portable.
|
|
|
|
.PP
|
|
|
|
The pointer
|
|
|
|
representation on the
|
|
|
|
PDP-11
|
|
|
|
corresponds to a 16-bit integer and
|
|
|
|
measures bytes.
|
|
|
|
The
|
|
|
|
.B
|
|
|
|
char\fR's
|
|
|
|
have no alignment requirements; everything else must have an even address.
|
|
|
|
.PP
|
|
|
|
On the
|
|
|
|
VAX-11,
|
|
|
|
pointers are 32 bits long and measure bytes.
|
|
|
|
Elementary objects are aligned on a boundary equal to their
|
|
|
|
length, except that
|
|
|
|
.B
|
|
|
|
double
|
|
|
|
.R
|
|
|
|
quantities need be aligned only on even 4-byte boundaries.
|
|
|
|
Aggregates are aligned on the strictest boundary required by
|
|
|
|
any of their constituents.
|
|
|
|
.PP
|
|
|
|
The 3B 20 computer has 24-bit pointers placed into 32-bit quantities.
|
|
|
|
Most objects are
|
|
|
|
aligned on 4-byte boundaries. \fBShort\fRs are aligned in all cases on
|
|
|
|
2-byte boundaries. Arrays of characters, all structures,
|
|
|
|
\fBint\fR\^s, \fBlong\fR\^s, \fBfloat\fR\^s, and \fBdouble\fR\^s are aligned on 4-byte
|
2002-10-12 14:50:50 +00:00
|
|
|
boundaries; but structure members may be packed tighter.
|
2002-05-19 06:17:52 +00:00
|
|
|
.nr Hu 1
|
|
|
|
.NH 2
|
|
|
|
CONSTANT EXPRESSIONS
|
|
|
|
.PP
|
|
|
|
In several places C requires expressions that evaluate to
|
|
|
|
a constant:
|
|
|
|
after
|
|
|
|
\fBcase\fR,
|
|
|
|
as array bounds, and in initializers.
|
|
|
|
In the first two cases, the expression can
|
|
|
|
involve only integer constants, character constants,
|
|
|
|
casts to integral types,
|
|
|
|
enumeration constants,
|
|
|
|
and
|
|
|
|
.B
|
|
|
|
sizeof
|
|
|
|
.R
|
|
|
|
expressions, possibly
|
|
|
|
connected by the binary operators
|
|
|
|
.ne 10
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\(pl \(mi \(** / % & | ^ << >> == != < > <= >= && ||
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
or by the unary operators
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\(mi \s+2~\s0
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
or by the ternary operator
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
?:
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
Parentheses can be used for grouping
|
|
|
|
but not for function calls.
|
|
|
|
.PP
|
|
|
|
More latitude is permitted for initializers;
|
|
|
|
besides constant expressions as discussed above,
|
|
|
|
one can also use floating constants
|
|
|
|
and arbitrary casts and
|
|
|
|
can also apply the unary
|
|
|
|
.B
|
|
|
|
&
|
|
|
|
.R
|
|
|
|
operator to external or static objects
|
|
|
|
and to external or static arrays subscripted
|
|
|
|
with a constant expression.
|
|
|
|
The unary
|
|
|
|
.B
|
|
|
|
&
|
|
|
|
.R
|
|
|
|
can also
|
|
|
|
be applied implicitly
|
|
|
|
by appearance of unsubscripted arrays and functions.
|
|
|
|
The basic rule is that initializers must
|
|
|
|
evaluate either to a constant or to the address
|
|
|
|
of a previously declared external or static object plus or minus a constant.
|
|
|
|
.nr Hu 1
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
Portability Considerations
|
|
|
|
.PP
|
|
|
|
Certain parts of C are inherently machine dependent.
|
|
|
|
The following list of potential trouble spots
|
|
|
|
is not meant to be all-inclusive
|
|
|
|
but to point out the main ones.
|
|
|
|
.PP
|
|
|
|
Purely hardware issues like
|
|
|
|
word size and the properties of floating point arithmetic and integer division
|
|
|
|
have proven in practice to be not much of a problem.
|
|
|
|
Other facets of the hardware are reflected
|
|
|
|
in differing implementations.
|
|
|
|
Some of these,
|
|
|
|
particularly sign extension
|
|
|
|
(converting a negative character into a negative integer)
|
|
|
|
and the order in which bytes are placed in a word,
|
|
|
|
are nuisances that must be carefully watched.
|
|
|
|
Most of the others are only minor problems.
|
|
|
|
.PP
|
|
|
|
The number of
|
|
|
|
.B
|
|
|
|
register
|
|
|
|
.R
|
|
|
|
variables that can actually be placed in registers
|
|
|
|
varies from machine to machine
|
|
|
|
as does the set of valid types.
|
|
|
|
Nonetheless, the compilers all do things properly for their own machine;
|
|
|
|
excess or invalid
|
|
|
|
.B
|
|
|
|
register
|
|
|
|
.R
|
|
|
|
declarations are ignored.
|
|
|
|
.PP
|
|
|
|
Some difficulties arise only when
|
|
|
|
dubious coding practices are used.
|
|
|
|
It is exceedingly unwise to write programs
|
|
|
|
that depend
|
|
|
|
on any of these properties.
|
|
|
|
.PP
|
|
|
|
The order of evaluation of function arguments
|
|
|
|
is not specified by the language.
|
|
|
|
The order in which side effects take place
|
|
|
|
is also unspecified.
|
|
|
|
.PP
|
|
|
|
Since character constants are really objects of type
|
|
|
|
\fBint\fR,
|
|
|
|
multicharacter character constants may be permitted.
|
|
|
|
The specific implementation
|
|
|
|
is very machine dependent
|
|
|
|
because the order in which characters
|
|
|
|
are assigned to a word
|
|
|
|
varies from one machine to another.
|
|
|
|
.PP
|
|
|
|
Fields are assigned to words and characters to integers right to left
|
|
|
|
on some machines
|
|
|
|
and left to right on other machines.
|
|
|
|
These differences are invisible to isolated programs
|
|
|
|
that do not indulge in type punning (e.g.,
|
|
|
|
by converting an
|
|
|
|
.B
|
|
|
|
int
|
|
|
|
.R
|
|
|
|
pointer to a
|
|
|
|
.B
|
|
|
|
char
|
|
|
|
.R
|
|
|
|
pointer and inspecting the pointed-to storage)
|
|
|
|
but must be accounted for when conforming to externally-imposed
|
|
|
|
storage layouts.
|
|
|
|
.nr Hu 1
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 1
|
2002-05-19 06:17:52 +00:00
|
|
|
Syntax Summary
|
|
|
|
.PP
|
|
|
|
This summary of C syntax is intended more for aiding comprehension
|
|
|
|
than as an exact statement of the language.
|
|
|
|
.nr Hu 1
|
|
|
|
.ne 18
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Expressions
|
|
|
|
.PP
|
|
|
|
The basic expressions are:
|
|
|
|
.tr ~~
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIexpression:
|
|
|
|
primary
|
|
|
|
\(** expression\fR
|
|
|
|
&\fIlvalue
|
|
|
|
\(mi expression
|
|
|
|
! expression
|
|
|
|
\s+2~\s0 expression
|
|
|
|
\(pl\(pl lvalue
|
|
|
|
\(mi\(milvalue
|
|
|
|
lvalue \(pl\(pl
|
|
|
|
lvalue \(mi\(mi
|
|
|
|
\fBsizeof\fI expression
|
|
|
|
\fBsizeof (\fItype-name\fB)\fI
|
|
|
|
( type-name ) expression
|
|
|
|
expression binop expression
|
|
|
|
expression ? expression : expression
|
|
|
|
lvalue asgnop expression
|
|
|
|
expression , expression
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIprimary:
|
|
|
|
identifier
|
|
|
|
constant
|
|
|
|
string
|
|
|
|
( expression )
|
|
|
|
primary ( expression-list\v'0.5'\s-2opt\s0\v'-0.5' )
|
|
|
|
primary [ expression ]
|
|
|
|
primary . identifier
|
|
|
|
primary \(mi identifier
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIlvalue:
|
|
|
|
identifier
|
|
|
|
primary [ expression ]
|
|
|
|
lvalue . identifier
|
|
|
|
primary \(mi identifier
|
|
|
|
\(** expression
|
|
|
|
( lvalue )\fR
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
.PP
|
|
|
|
The primary-expression operators
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
() [] . \(mi
|
|
|
|
.tr ~~
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
have highest priority and group left to right.
|
|
|
|
The unary operators
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\(** & \(mi ! \s+2~\s0 \(pl\(pl \(mi\(mi \fBsizeof\fI ( type-name \fR)
|
|
|
|
.DE
|
|
|
|
.LP
|
|
|
|
have priority below the primary operators
|
|
|
|
but higher than any binary operator
|
|
|
|
and group right to left.
|
|
|
|
Binary operators
|
|
|
|
group left to right; they have priority
|
|
|
|
decreasing
|
|
|
|
as indicated below.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIbinop:\fR
|
|
|
|
\(** / %
|
|
|
|
\(pl \(mi
|
|
|
|
>> <<
|
|
|
|
< > <= >=
|
|
|
|
== !=
|
|
|
|
&
|
|
|
|
^
|
|
|
|
|
|
|
|
|
&&
|
|
|
|
||
|
|
|
|
.DE
|
|
|
|
The conditional operator groups right to left.
|
|
|
|
.PP
|
|
|
|
Assignment operators all have the same
|
|
|
|
priority and all group right to left.
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIasgnop:\fR
|
|
|
|
= \(pl= \(mi= \(**= /= %= >>= <<= &= ^= |=
|
|
|
|
.DE
|
|
|
|
.PP
|
|
|
|
The comma operator has the lowest priority and groups left to right.
|
|
|
|
.nr Hu 1
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Declarations
|
|
|
|
.PP
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIdeclaration:
|
|
|
|
decl-specifiers init-declarator-list\v'0.5'\s-2opt\s0\v'-0.5' ;
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIdecl-specifiers:
|
|
|
|
type-specifier decl-specifiers\v'0.5'\s-2opt\s0\v'-0.5'
|
|
|
|
sc-specifier decl-specifiers\v'0.5'\s-2opt\s0\v'-0.5'
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIsc-specifier:\fB
|
|
|
|
auto
|
|
|
|
static
|
|
|
|
extern
|
|
|
|
register
|
|
|
|
typedef
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fItype-specifier:
|
|
|
|
struct-or-union-specifier
|
|
|
|
typedef-name
|
|
|
|
enum-specifier
|
|
|
|
basic-type-specifier:
|
|
|
|
basic-type
|
|
|
|
basic-type basic-type-specifiers
|
|
|
|
basic-type:\fB
|
|
|
|
char
|
|
|
|
short
|
|
|
|
int
|
|
|
|
long
|
|
|
|
unsigned
|
|
|
|
float
|
|
|
|
double
|
|
|
|
void\fR
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIenum-specifier:\fB
|
|
|
|
enum\fI { enum-list }\fB
|
|
|
|
enum \fIidentifier { enum-list }\fB
|
|
|
|
enum \fIidentifier
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIenum-list:
|
|
|
|
enumerator
|
|
|
|
enum-list , enumerator
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIenumerator:
|
|
|
|
identifier
|
|
|
|
identifier = constant-expression
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIinit-declarator-list:
|
|
|
|
init-declarator
|
|
|
|
init-declarator , init-declarator-list
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIinit-declarator:
|
|
|
|
declarator initializer\v'0.5'\s-2opt\s0\v'-0.5'
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIdeclarator:
|
|
|
|
identifier
|
|
|
|
( declarator )
|
|
|
|
\(** declarator
|
|
|
|
declarator ()
|
|
|
|
declarator [ constant-expression\v'0.5'\s-2opt\s0\v'-0.5' ]
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIstruct-or-union-specifier:\fB
|
|
|
|
struct\fI { struct-decl-list }\fB
|
|
|
|
struct \fIidentifier { struct-decl-list }\fB
|
|
|
|
struct \fIidentifier\fB
|
|
|
|
union { \fIstruct-decl-list }\fB
|
|
|
|
union \fIidentifier { struct-decl-list }\fB
|
|
|
|
union \fIidentifier
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIstruct-decl-list:
|
|
|
|
struct-declaration
|
|
|
|
struct-declaration struct-decl-list
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIstruct-declaration:
|
|
|
|
type-specifier struct-declarator-list ;
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIstruct-declarator-list:
|
|
|
|
struct-declarator
|
|
|
|
struct-declarator , struct-declarator-list
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIstruct-declarator:
|
|
|
|
declarator
|
|
|
|
declarator : constant-expression
|
|
|
|
: constant-expression
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIinitializer:
|
|
|
|
= expression
|
|
|
|
= { initializer-list }
|
|
|
|
= { initializer-list , }
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIinitializer-list:
|
|
|
|
expression
|
|
|
|
initializer-list , initializer-list
|
|
|
|
{ initializer-list }
|
|
|
|
{ initializer-list , }
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fItype-name:
|
|
|
|
type-specifier abstract-declarator
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIabstract-declarator:
|
|
|
|
empty
|
|
|
|
( abstract-declarator )
|
|
|
|
\(** abstract-declarator
|
|
|
|
abstract-declarator ()
|
|
|
|
abstract-declarator [ constant-expression\v'0.5'\s-2opt\s0\v'-0.5' ]
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fItypedef-name:
|
|
|
|
identifier
|
|
|
|
.nr Hu 1
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
Statements
|
|
|
|
.PP
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIcompound-statement:
|
|
|
|
{ declaration-list\v'0.5'\s-2opt\s0\v'-0.5' statement-list\v'0.5'\s-2opt\s0\v'-0.5' }
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIdeclaration-list:
|
|
|
|
declaration
|
|
|
|
declaration declaration-list
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIstatement-list:
|
|
|
|
statement
|
|
|
|
statement statement-list
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.DS
|
2002-05-19 06:17:52 +00:00
|
|
|
\fIstatement:
|
|
|
|
compound-statement
|
|
|
|
expression ;
|
|
|
|
\fBif\fI ( expression ) statement
|
|
|
|
\fBif\fI ( expression ) statement \fBelse\fI statement
|
|
|
|
\fBwhile\fI ( expression ) statement
|
|
|
|
\fBdo\fI statement \fBwhile\fI ( expression ) ;
|
|
|
|
\fBfor\fI (exp\v'0.3'\s-2opt\s0\v'-0.3'\fB;\fIexp\v'0.3'\s-2opt\s0\v'-0.3'\fB;\fIexp\v'0.3'\s-2opt\s0\v'-0.3'\fI) statement
|
|
|
|
\fBswitch\fI ( expression ) statement
|
|
|
|
\fBcase\fI constant-expression : statement
|
|
|
|
\fBdefault\fI : statement
|
|
|
|
\fBbreak ;
|
|
|
|
continue ;
|
|
|
|
return ;
|
|
|
|
return\fI expression ;
|
|
|
|
\fBgoto\fI identifier ;
|
|
|
|
identifier : statement
|
|
|
|
;\fR
|
|
|
|
.nr Hu 1
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH 2
|
2002-05-19 06:17:52 +00:00
|
|
|
External definitions
|
|
|
|
.PP
|
|
|
|
.DS
|
|
|
|
\fIprogram:
|
|
|
|
external-definition
|
|
|
|
external-definition program
|
|
|
|
.DE
|
|
|
|
.DS
|
|
|
|
\fIexternal-definition:
|
|
|
|
function-definition
|
|
|
|
data-definition
|
|
|
|
.DE
|
|
|
|
.DS
|
|
|
|
\fIfunction-definition:
|
|
|
|
decl-specifier\v'0.5'\s-2opt\s0\v'-0.5' function-declarator function-body
|
|
|
|
.DE
|
|
|
|
.DS
|
|
|
|
\fIfunction-declarator:
|
|
|
|
declarator ( parameter-list\v'0.5'\s-2opt\s0\v'-0.5' )
|
|
|
|
.DE
|
|
|
|
.DS
|
|
|
|
\fIparameter-list:
|
|
|
|
identifier
|
|
|
|
identifier , parameter-list
|
|
|
|
.DE
|
|
|
|
.DS
|
|
|
|
\fIfunction-body:
|
|
|
|
declaration-list\v'0.5'\s-2opt\s0\v'-0.5' compound-statement
|
|
|
|
.DE
|
|
|
|
.DS
|
|
|
|
\fIdata-definition:
|
|
|
|
\fBextern\fI declaration\fB ;
|
|
|
|
\fBstatic\fI declaration\fB ;
|
|
|
|
.DE
|
2002-10-12 14:50:50 +00:00
|
|
|
.NH
|
2002-05-19 06:17:52 +00:00
|
|
|
Preprocessor
|
|
|
|
.DS
|
|
|
|
\fB#define\fI identifier token-string\v'0.3'\s-2opt\s0\v'-0.3'\fB
|
|
|
|
\fB#define\fI identifier\fB(\fIidentifier\fB,...)\fItoken-string\v'0.5'\s-2opt\s0\v'-0.5'\fB
|
|
|
|
\fB#undef\fI identifier\fB
|
|
|
|
\fB#include "\fIfilename\|\fB"
|
|
|
|
#include <\fIfilename\|\fB>
|
|
|
|
\fB#if\fI restricted-constant-expression\fB
|
|
|
|
\fB#ifdef\fI identifier\fB
|
|
|
|
\fB#ifndef\fI identifier\fB
|
|
|
|
\fB#else
|
|
|
|
\fB#endif
|
|
|
|
\fB#line\fI constant \fB"\fIfilename\|\fB"
|
|
|
|
.sp 5
|
|
|
|
.DE
|
2002-05-19 06:55:13 +00:00
|
|
|
.\" .TC 2 1 3 0
|