diff docs/ccguide/creference.appendix @ 1065:63fc27187545

Appendix A from "The C Programming Language, 1978" found on the Internet
author roug
date Sun, 30 Mar 2003 08:27:32 +0000
parents
children c8fcb9426d8b
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/ccguide/creference.appendix	Sun Mar 30 08:27:32 2003 +0000
@@ -0,0 +1,4225 @@
+<appendix>
+<title>C Reference Manual</title>
+<sect1><title>Introduction</title>
+<para>
+This manual describes the C language on the DEC PDP-11<footnote><para>
+DEC PDP-11, and DEC VAX-11 are trademarks of Digital Equipment Corporation.
+</para></footnote>, the DEC VAX-11,
+and the 6809<footnote><para>
+6809 is a trademark of Motorola.
+</para></footnote>.
+Where differences exist, it concentrates on the VAX, but tries to point
+out implementation-dependent details.  With few execptions, these dependencies
+follow directly from the underlying properties of the hardware; the various
+compilers are generally quite compatible.
+</para></sect1>
+<sect1><title>Lexical Conventions</title>
+<para>
+There are six classes of tokens -
+identifiers, keywords, constants, strings, operators, and other separators.
+Blanks, tabs, newlines,
+and comments (collectively, <quote>white space</quote>) 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.
+</para><para>
+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.
+</para>
+<sect2><title>Comments</title>
+<para>
+The characters
+<literal>
+/*
+</literal>
+introduce a comment which terminates
+with the characters
+<literal>*/</literal>.
+Comments do not nest.
+</para></sect2>
+<sect2><title>Identifiers (Names)</title>
+<para>
+An identifier is a sequence of letters and digits.
+The first character must be a letter.
+The underscore
+(<literal>_</literal>)
+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:
+<informaltable frame="none"> 
+<tgroup cols="2">
+<tbody>
+<row>
+  <entry>PDP-11</entry>
+  <entry>7 characters, 2 cases</entry>
+</row>
+<row>
+  <entry>VAX-11</entry>
+  <entry>>100 characters, 2 cases</entry>
+</row>
+<row>
+  <entry>Motorola 6809</entry>
+  <entry>7 characters, 2 cases</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</para></sect2>
+<sect2><title>Keywords</title>
+<para>
+The following identifiers are reserved for use
+as keywords and may not be used otherwise:
+<informaltable frame="none"> 
+<tgroup cols="5">
+<tbody>
+<row>
+  <entry>auto</entry>
+  <entry>do</entry>
+  <entry>for</entry>
+  <entry>return</entry>
+  <entry>typedef</entry>
+</row>
+<row>
+  <entry>break</entry>
+  <entry>double</entry>
+  <entry>goto</entry>
+  <entry>short</entry>
+  <entry>union</entry>
+</row>
+<row>
+  <entry>case</entry>
+  <entry>else</entry>
+  <entry>if</entry>
+  <entry>sizeof</entry>
+  <entry>unsigned</entry>
+</row>
+<row>
+  <entry>char</entry>
+  <entry>enum</entry>
+  <entry>int</entry>
+  <entry>static</entry>
+  <entry>direct</entry>
+</row>
+<row>
+  <entry>continue</entry>
+  <entry>external</entry>
+  <entry>long</entry>
+  <entry>struct</entry>
+  <entry>while</entry>
+</row>
+<row>
+  <entry>default</entry>
+  <entry>float</entry>
+  <entry>register</entry>
+  <entry>switch</entry>
+  <entry></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</para><para> 
+Some implementations also reserve the words
+<literal>fortran</literal>
+and
+<literal>asm</literal>
+</para></sect2>
+<sect2><title>Constants</title>
+<para>
+There are several kinds
+of constants.
+Each has a type; an introduction to types is given in <quote>NAMES.</quote>
+Hardware characteristics that affect sizes are summarized in
+<quote>Hardware Characteristics</quote> under <quote>LEXICAL CONVENTIONS.</quote>
+</para>
+<sect3><title>Integer Constants</title>
+<para>
+An integer constant consisting of a sequence of digits
+is taken
+to be octal if it begins with
+<literal>
+0
+</literal>
+(digit zero).
+An octal constant consists of the digits <literal>0</literal> through <literal>7</literal> only.
+A sequence of digits preceded by
+<literal>0x</literal>
+or
+<literal>0X</literal>
+(digit zero) is taken to be a hexadecimal integer.
+The hexadecimal digits include
+<literal>
+a
+</literal>
+or
+<literal>A</literal>
+through
+<literal>f</literal>
+or
+<literal>F</literal>
+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
+<literal>long</literal>;
+an octal or hex constant which exceeds the largest unsigned machine integer
+is likewise taken to be
+<literal>long</literal>.
+</para></sect3>
+<sect3><title>Explicit Long Constants</title>
+<para>
+A decimal, octal, or hexadecimal integer constant immediately followed
+by
+<literal>
+l
+</literal>
+(letter ell)
+or
+<literal>
+L
+</literal>
+is a long constant.
+As discussed below,
+on some machines
+integer and long values may be considered identical.
+</para></sect3>
+<sect3><title>Character Constants</title>
+<para>
+A character constant is a character enclosed in single quotes,
+as in '<literal>x</literal>'.
+The value of a character constant is the numerical value of the
+character in the machine's character set.
+</para><para>
+Certain nongraphic characters,
+the single quote
+(<literal>'</literal>)
+and the backslash
+(<literal>\</literal>),
+may be represented according to the following table
+of escape sequences:
+<informaltable frame="none">
+<tgroup cols="3">
+<colspec colwidth="2in"/>
+<colspec colwidth="1in"/>
+<colspec colwidth="1in"/>
+<tbody>
+<row>
+  <entry>newline</entry>
+  <entry>NL (LF)</entry>
+  <entry>\n</entry>
+</row>
+<row>
+  <entry>horizontal tab</entry>
+  <entry>HT</entry>
+  <entry>\t</entry>
+</row>
+<row>
+  <entry>vertical tab</entry>
+  <entry>VT</entry>
+  <entry>\v</entry>
+</row>
+<row>
+  <entry>backspace</entry>
+  <entry>BS</entry>
+  <entry>\b</entry>
+</row>
+<row>
+  <entry>carriage return</entry>
+  <entry>CR</entry>
+  <entry>\r</entry>
+</row>
+<row>
+  <entry>form feed</entry>
+  <entry>FF</entry>
+  <entry>\f</entry>
+</row>
+<row>
+  <entry>backslash</entry>
+  <entry>\</entry>
+  <entry>\\</entry>
+</row>
+<row>
+  <entry>single quote</entry>
+  <entry>'</entry>
+  <entry>\'</entry>
+</row>
+<row>
+  <entry>bit pattern</entry>
+  <entry><emphasis>ddd</emphasis></entry>
+  <entry>\<emphasis>ddd</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</para><para> 
+The escape
+\<emphasis>ddd</emphasis>
+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
+<literal>
+\0
+</literal>
+(not followed
+by a digit), which indicates the character
+<literal>
+NUL</literal>.
+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 <literal>int</literal>.
+</para></sect3>
+<sect3><title>Floating Constants</title>
+<para>
+A floating constant consists of
+an integer part, a decimal point, a fraction part,
+an
+<literal>
+e
+</literal>
+or
+<literal>E</literal>,
+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
+<literal>
+e
+</literal>
+and the exponent (not both) may be missing.
+Every floating constant has type <literal>double</literal>.
+</para></sect3>
+<sect3><title>Enumeration Constants</title>
+<para>
+Names declared as enumerators
+(see <quote>Structure, Union, and Enumeration Declarations</quote> under
+<quote>DECLARATIONS</quote>)
+have type <literal>int</literal>.
+</para></sect3></sect2>
+<sect2><title>Strings</title>
+<para>
+A string is a sequence of characters surrounded by
+double quotes,
+as in
+<literal>&quot;...&quot;</literal>.
+A string has type
+<quote>array of <literal>char</literal></quote> and storage class
+<literal>static</literal>
+(see <quote>NAMES</quote>)
+and is initialized with
+the given characters.
+The compiler places
+a null byte
+(<literal>\0</literal>)
+at the end of each string so that programs
+which scan the string can
+find its end.
+In a string, the double quote character
+(<literal>&quot;</literal>)
+must be preceded by
+a
+<literal>\</literal>;
+in addition, the same escapes as described for character
+constants may be used.
+</para><para>
+A
+<literal>
+\
+</literal>
+and
+the immediately following newline are ignored.
+All strings, even when written identically, are distinct.
+</para></sect2>
+<sect2><title>Hardware Characteristics</title>
+<para>
+The following figure summarize
+certain hardware properties that vary from machine to machine.
+<table frame="none">
+<title>DEC PDP-11 HARDWARE CHARACTERISTICS</title>
+<tgroup cols="4">
+<thead>
+<row>
+  <entry></entry>
+  <entry>DEC PDP\-11</entry>
+  <entry>DEC VAX-11</entry>
+  <entry>6809</entry>
+</row>
+<row>
+  <entry></entry>
+  <entry>(ASCII)</entry>
+  <entry>(ASCII)</entry>
+  <entry>(ASCII)</entry>
+</row>
+</thead>
+<tbody>
+<row>
+  <entry>char</entry>
+  <entry>8 bits</entry>
+  <entry>8 bits</entry>
+  <entry>8 bits</entry>
+</row>
+<row>
+  <entry>int</entry>
+  <entry>16</entry>
+  <entry>32</entry>
+  <entry>16</entry>
+</row>
+<row>
+  <entry>short</entry>
+  <entry>16</entry>
+  <entry>16</entry>
+  <entry>16</entry>
+</row>
+<row>
+  <entry>long</entry>
+  <entry>32</entry>
+  <entry>32</entry>
+  <entry>32</entry>
+</row>
+<row>
+  <entry>float</entry>
+  <entry>32</entry>
+  <entry>32</entry>
+  <entry>32</entry>
+</row>
+<row>
+  <entry>double</entry>
+  <entry>64</entry>
+  <entry>64</entry>
+  <entry>64</entry>
+</row>
+<row>
+  <entry>float range</entry>
+  <entry>&plusmn;10<superscript>&plusmn;38</superscript></entry>
+  <entry>&plusmn;10<superscript>&plusmn;38</superscript></entry>
+  <entry>&plusmn;10<superscript>&plusmn;38</superscript></entry>
+</row>
+<row>
+  <entry>double range</entry>
+  <entry>&plusmn;10<superscript>&plusmn;38</superscript></entry>
+  <entry>&plusmn;10<superscript>&plusmn;38</superscript></entry>
+  <entry>&plusmn;10<superscript>&plusmn;38</superscript></entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+</para><para>
+</para></sect2></sect1>
+<sect1><title>
+Syntax Notation
+</title><para>
+Syntactic categories are indicated by
+<emphasis>
+italic
+</emphasis>
+type
+and literal words and characters
+in
+<literal>bold</literal>
+type.
+Alternative categories are listed on separate lines.
+An optional terminal or nonterminal symbol is
+indicated by the subscript <quote>opt,</quote> so that
+<literallayout>
+{ <emphasis>expression<subscript>opt</subscript></emphasis> }
+</literallayout>
+
+indicates an optional expression enclosed in braces.
+The syntax is summarized in <quote>SYNTAX SUMMARY</quote>.
+</para></sect1>
+<sect1><title>
+What's in a name?
+</title><para>
+C bases the interpretation of an
+identifier upon two attributes of the identifier: its
+<emphasis>storage class</emphasis>
+and its
+<emphasis>type</emphasis>.
+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.
+</para>
+<para>
+There are four declarable storage classes:
+automatic, static, external, and register.
+Automatic variables are local to each invocation of
+a block (see <quote>Compound Statement or Block</quote> in 
+<quote>STATEMENTS</quote>) 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.
+</para>
+<para>
+C supports several fundamental types of objects:
+</para>
+<para>
+Objects declared as characters
+(<literal>char</literal>)
+are large enough to store any member of the implementation's
+character set, 
+and if a genuine character from that character set is
+stored in a <literal>char</literal> 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.
+</para><para>
+Up to three sizes of integer, declared
+<literal>short int</literal>,
+<literal>int</literal>,
+and
+<literal>long int</literal>,
+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.
+<quote>Plain</quote> integers have the natural size suggested
+by the host machine architecture.
+The other sizes are provided to meet special needs.
+</para><para>
+Unsigned
+integers, declared
+<literal>unsigned</literal>,
+obey the laws of arithmetic modulo
+2<superscript><emphasis>n</emphasis></superscript>
+where <emphasis>n</emphasis> is the number of bits in the representation.
+(On the
+PDP-11,
+unsigned long quantities are not supported.)
+</para><para>
+Single-precision floating point
+(<literal>float</literal>)
+and double precision floating point
+(<literal>double</literal>)
+may be synonymous in some implementations.
+</para><para>
+Because objects of the foregoing types can usefully be interpreted
+as numbers, they will be referred to as
+<emphasis>
+arithmetic
+</emphasis>
+types.
+Types
+<literal>char</literal>,
+<literal>int</literal>
+of all sizes whether <literal>unsigned</literal> or not, and
+<literal>
+enum
+</literal>
+will collectively be called
+<emphasis>
+integral
+</emphasis>
+types.
+The
+<literal>float</literal>
+and
+<literal>double</literal>
+types will collectively be called
+<emphasis>floating</emphasis>
+types.
+</para><para>
+Besides the fundamental arithmetic types, there is a
+conceptually infinite class of derived types constructed
+from the fundamental types in the following ways:
+<itemizedlist>
+<listitem><para>
+<emphasis>Arrays</emphasis>
+of objects of most types
+</para></listitem>
+<listitem><para>
+<emphasis>Functions</emphasis>
+which return objects of a given type
+</para></listitem>
+<listitem><para>
+<emphasis>Pointers</emphasis>
+to objects of a given type
+</para></listitem>
+<listitem><para>
+<emphasis>Structures</emphasis>
+containing a sequence of objects of various types
+</para></listitem>
+<listitem><para>
+<emphasis>Unions</emphasis>
+capable of containing any one of several objects of various types.
+</para></listitem>
+</itemizedlist>
+</para><para>
+In general these methods
+of constructing objects can
+be applied recursively.
+</para></sect1>
+<sect1><title>Objects and lvalues</title>
+<para>
+An
+<emphasis>
+object
+</emphasis>
+is a manipulatable region of storage.
+An
+<emphasis>
+lvalue
+</emphasis>
+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
+<literal>
+E
+</literal>
+is an expression of pointer type, then
+<literal>
+*E
+</literal>
+is an lvalue
+expression referring to the object to which
+<literal>
+E
+</literal>
+points.
+The name <quote>lvalue</quote> comes from the assignment expression
+<literal>
+E1\ =\ E2
+</literal>
+in which the left operand
+<literal>
+E1
+</literal>
+must be
+an lvalue expression.
+The discussion of each operator
+below indicates whether it expects lvalue operands and whether it
+yields an lvalue.
+</para></sect1>
+<sect1><title>
+Conversions
+</title><para>
+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
+<quote>Arithmetic Conversions.</quote>
+The summary will be supplemented
+as required by the discussion
+of each operator.
+</para>
+<sect2><title>Characters and Integers</title>
+<para>
+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,
+<literal>char</literal>
+variables range in value from
+-128 to 127.
+The more explicit type
+<literal>unsigned</literal>
+<literal>char</literal>
+forces the values to range from 0 to 255.
+</para><para>
+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,
+<literal>'\377'</literal>
+has the value
+<literal>
+-1</literal>.
+</para><para>
+When a longer integer is converted to a shorter
+integer
+or to a
+<literal>char</literal>,
+it is truncated on the left.
+Excess bits are simply discarded.
+</para></sect2>
+<sect2><title>Float and Double</title>
+<para>
+All floating arithmetic in C is carried out in double precision.
+Whenever a
+<literal>float</literal>
+appears in an expression it is lengthened to
+<literal>double</literal>
+by zero padding its fraction.
+When a
+<literal>double</literal>
+must be
+converted to
+<literal>float</literal>,
+for example by an assignment,
+the
+<literal>double</literal>
+is rounded before
+truncation to
+<literal>float</literal>
+length.
+This result is undefined if it cannot be represented as a float.
+On the VAX, the compiler can be directed to use single percision for expressions
+containing only float and interger operands.
+</para></sect2>
+<sect2><title>Floating and Integral</title>
+<para>
+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.
+</para><para>
+Conversions of integral values to floating type
+are well behaved.
+Some loss of accuracy occurs
+if the destination lacks sufficient bits.
+</para></sect2>
+<sect2><title>Pointers and Integers</title>
+<para>
+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.
+</para></sect2>
+<sect2><title>Unsigned</title>
+<para>
+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<superscript>wordsize</superscript>).
+In a 2's complement representation,
+this conversion is conceptual; and there is no actual change in the
+bit pattern.
+</para><para>
+When an unsigned <literal>short</literal> integer is converted to
+<literal>long</literal>,
+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.
+</para></sect2>
+<sect2><title>Arithmetic Conversions</title>
+<para>
+A great many operators cause conversions
+and yield result types in a similar way.
+This pattern will be called the <quote>usual arithmetic conversions.</quote>
+<orderedlist numeration="loweralpha">
+<listitem><para>
+First, any operands of type
+<literal>char</literal>
+or
+<literal>short</literal>
+are converted to
+<literal>int</literal>,
+and any operands of type <literal>unsigned char</literal>
+or <literal>unsigned short</literal> are converted
+to <literal>unsigned int</literal>.
+</para></listitem>
+<listitem><para>
+Then, if either operand is
+<literal>double</literal>,
+the other is converted to
+<literal>double</literal>
+and that is the type of the result.
+</para></listitem>
+<listitem><para>
+Otherwise, if either operand is <literal>unsigned long</literal>,
+the other is converted to <literal>unsigned long</literal> and that
+is the type of the result.
+</para></listitem>
+<listitem><para>
+Otherwise, if either operand is
+<literal>long</literal>,
+the other is converted to
+<literal>long</literal>
+and that is the type of the result.
+</para></listitem>
+<listitem><para>
+Otherwise, if one operand is <literal>long</literal>, and
+the other is <literal>unsigned int</literal>, they are both
+converted to <literal>unsigned long</literal> and that is
+the type of the result.
+</para></listitem>
+<listitem><para>
+Otherwise, if either operand is
+<literal>unsigned</literal>,
+the other is converted to
+<literal>unsigned</literal>
+and that is the type of the result.
+</para></listitem>
+<listitem><para>
+Otherwise, both operands must be
+<literal>int</literal>,
+and that is the type of the result.
+</para></listitem>
+</orderedlist>
+</para></sect2></sect1>
+<sect1><title>
+Expressions
+</title><para>
+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
+<literal>
++
+</literal>
+(see <quote>Additive Operators</quote>)
+are those expressions defined under <quote>Primary Expressions</quote>,
+<quote>Unary Operators</quote>, and <quote>Multiplicative Operators</quote>.
+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 <quote>SYNTAX SUMMARY</quote>.
+</para><para>
+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
+(<literal>*,</literal>
+<literal>+</literal>,
+<literal>&amp;</literal>,
+<literal>|</literal>,
+<literal>^</literal>)
+may be rearranged arbitrarily even in the presence
+of parentheses;
+to force a particular order of evaluation,
+an explicit temporary must be used.
+</para><para>
+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.
+</para>
+<sect2><title>Primary Expressions</title>
+<para>
+Primary expressions
+involving <literal>.</literal>,
+<literal>-></literal>,
+subscripting, and function calls
+group left to right.
+<literallayout> 
+<emphasis>primary-expression:
+        identifier
+        constant
+        string
+        ( expression )
+        primary-expression [ expression ]
+        primary-expression ( expression-list<subscript>opt</subscript> )
+        primary-expression . identifier
+        primary-expression -> identifier</emphasis>
+</literallayout>
+<literallayout> 
+<emphasis>expression-list:
+        expression
+        expression-list , expression</emphasis>
+</literallayout>
+</para><para>
+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 <quote>array of ...</quote>,
+then the value of the identifier expression
+is a pointer
+to the first object in the array; and the
+type of the expression is
+<quote>pointer to ...</quote>.
+Moreover, an array identifier is not an lvalue
+expression.
+Likewise, an identifier which is declared
+<quote>function returning ...</quote>,
+when used except in the function-name position
+of a call, is converted to <quote>pointer to function returning ...</quote>.
+</para><para>
+A
+constant is a primary expression.
+Its type may be
+<literal>int</literal>,
+<literal>long</literal>,
+or
+<literal>double</literal>
+depending on its form.
+Character constants have type
+<literal>int</literal>
+and floating constants have type
+<literal>double</literal>.
+</para><para>
+A string is a primary expression.
+Its type is originally <quote>array of
+<literal>char</literal></quote>,
+but following
+the same rule given above for identifiers,
+this is modified to <quote>pointer to
+<literal>char</literal></quote> and
+the
+result is a pointer to the first character
+in the string.
+(There is an exception in certain initializers;
+see <quote>Initialization</quote> under <quote>DECLARATIONS.</quote>)
+</para><para>
+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.
+</para><para>
+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 <quote>pointer to ...</quote>,
+the subscript expression is
+<literal>int</literal>,
+and the type of the result is <quote>...</quote>.
+The expression
+<literal>
+E1[E2]
+</literal>
+is
+identical (by definition) to
+<literal>
+*((E1)+E2))</literal>.
+All the clues
+needed to understand
+this notation are contained in this subpart together
+with the discussions
+in <quote>Unary Operators</quote> and <quote>Additive Operators</quote> on identifiers,
+<literal>
+* 
+</literal>
+and
+<literal>
++
+</literal>
+respectively.
+The implications are summarized under <quote>Arrays, Pointers, and Subscripting</quote>
+under <quote>TYPES REVISITED.</quote>
+</para><para>
+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 <quote>function returning ...,</quote>
+and the result of the function call is of type <quote>...</quote>.
+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.
+</para><para>
+Any actual arguments of type
+<literal>float</literal>
+are
+converted to
+<literal>double</literal>
+before the call.
+Any of type
+<literal>char</literal>
+or
+<literal>short</literal>
+are converted to
+<literal>int</literal>.
+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 <quote>Unary Operators</quote> and <quote>Type Names</quote> under
+<quote>DECLARATIONS.</quote>
+</para><para>
+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.
+</para><para>
+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.
+</para><para>
+A primary expression followed by an arrow (built from
+<literal>
+-
+</literal>
+and
+<literal>
+>
+</literal>
+)
+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
+<literal>
+E1->MOS
+</literal>
+is the same as
+<literal>
+(*E1).MOS</literal>.
+Structures and unions are discussed in
+<quote>Structure, Union, and Enumeration Declarations</quote> under
+<quote>DECLARATIONS.</quote>
+</para></sect2>
+<sect2><title>Unary Operators</title>
+<para>
+Expressions with unary operators
+group right to left.
+<literallayout> 
+<emphasis>unary-expression:
+        * expression
+        &amp; lvalue
+        - expression
+        ! expression
+        ~ expression
+        ++ lvalue
+        --lvalue
+        lvalue ++
+        lvalue --
+        ( type-name ) expression</emphasis>
+        sizeof<emphasis> expression</emphasis>
+        sizeof<emphasis> ( type-name )</emphasis>
+</literallayout>
+</para><para>
+The unary
+<literal>
+*
+</literal>
+operator
+means
+<emphasis>
+indirection
+</emphasis>
+;
+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 <quote>pointer to ...,</quote>
+the type of the result is <quote>...</quote>.
+</para><para>
+The result of the unary
+<literal>
+&amp;
+</literal>
+operator is a pointer
+to the object referred to by the
+lvalue.
+If the type of the lvalue is <quote>...</quote>,
+the type of the result is <quote>pointer to ...</quote>.
+</para><para>
+The result
+of the unary
+<literal>
+-
+</literal>
+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<superscript><emphasis>n</emphasis></superscript> where <emphasis>n</emphasis> is the number of bits in
+the corresponding signed type.
+
+There is no unary
+<literal>
++
+</literal>
+operator.
+</para><para>
+The result of the logical negation operator
+<literal>
+!
+</literal>
+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
+<literal>int</literal>.
+It is applicable to any arithmetic type
+or to pointers.
+</para><para>
+The
+<literal>
+~
+</literal>
+operator yields the one's complement of its operand.
+The usual arithmetic conversions are performed.
+The type of the operand must be integral.
+</para><para>
+The object referred to by the lvalue operand of prefix
+<literal>
+++
+</literal>
+is incremented.
+The value is the new value of the operand
+but is not an lvalue.
+The expression
+<literal>
+++x
+</literal>
+is equivalent to
+<literal>x=x+1</literal>.
+See the discussions <quote>Additive Operators</quote> and <quote>Assignment
+Operators</quote> for information on conversions.
+</para><para>
+The lvalue operand of prefix
+<literal>
+--
+</literal>
+is decremented
+analogously to the
+prefix
+<literal>
+++
+</literal>
+operator.
+</para><para>
+When postfix
+<literal>
+++
+</literal>
+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
+<literal>
+++
+</literal>
+operator.
+The type of the result is the same as the type of the lvalue expression.
+</para><para>
+When postfix
+<literal>
+--
+</literal>
+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
+<literal>
+--
+</literal>
+operator.
+The type of the result is the same as the type of the lvalue
+expression.
+</para><para>
+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
+<emphasis>
+cast</emphasis>.
+Type names are described in <quote>Type Names</quote> under <quote>Declarations.</quote>
+</para><para>
+The
+<literal>
+sizeof
+</literal>
+operator yields the size
+in bytes of its operand.
+(A
+<emphasis>
+byte
+</emphasis>
+is undefined by the language
+except in terms of the value of
+<literal>
+sizeof</literal>.
+However, in all existing implementations,
+a byte is the space required to hold a
+<literal>char</literal>.)
+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
+<literal>unsigned</literal>
+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.
+</para><para>
+The
+<literal>
+sizeof
+</literal>
+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.
+</para><para>
+The construction
+<literal>sizeof(</literal><emphasis>type</emphasis><literal>)</literal>
+is taken to be a unit,
+so the expression
+<literal>sizeof(</literal><emphasis>type</emphasis><literal>)-2</literal>
+is the same as
+<literal>(sizeof(</literal><emphasis>type</emphasis><literal>))-2</literal>.
+</para></sect2>
+<sect2><title>Multiplicative Operators</title>
+<para>
+The multiplicative operators
+<literal>*</literal>,
+<literal>/</literal>,
+and
+<literal>
+%
+</literal>
+group left to right.
+The usual arithmetic conversions are performed.
+<literallayout> 
+<emphasis>multiplicative expression:
+        expression * expression
+        expression / expression
+        expression % expression</emphasis>
+</literallayout>
+</para><para>
+The binary
+<literal>
+*
+</literal>
+operator indicates multiplication.
+The
+<literal>
+*
+</literal>
+operator is associative,
+and expressions with several multiplications at the same
+level may be rearranged by the compiler.
+The binary
+<literal>
+/
+</literal>
+operator indicates division.
+</para><para>
+The binary
+<literal>
+%
+</literal>
+operator yields the remainder
+from the division of the first expression by the second.
+The operands must be integral.
+</para><para>
+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
+<literal>
+(a/b)*b\ + a%b
+</literal>
+is equal to
+<literal>
+a
+</literal>
+(if
+<literal>
+b
+</literal>
+is not 0).
+</para></sect2>
+<sect2><title>Additive Operators</title>
+<para>
+The additive operators
+<literal>
++
+</literal>
+and
+<literal>
+-
+</literal>
+group left to right.
+The usual arithmetic conversions are performed.
+There are some additional type possibilities for each operator.
+<literallayout> 
+<emphasis>additive-expression:
+        expression + expression
+        expression - expression</emphasis>
+</literallayout>
+</para><para>
+The result of the
+<literal>
++
+</literal>
+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
+<literal>
+P
+</literal>
+is a pointer
+to an object in an array, the expression
+<literal>
+P+1
+</literal>
+is a pointer
+to the next object in the array.
+No further type combinations are allowed for pointers.
+</para><para>
+The
+<literal>
++
+</literal>
+operator is associative,
+and expressions with several additions at the same level may
+be rearranged by the compiler.
+</para><para>
+The result of the
+<literal>
+-
+</literal>
+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.
+</para><para>
+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
+<literal>int</literal>
+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.
+</para></sect2>
+<sect2><title>Shift Operators</title>
+<para>
+The shift operators
+<literal>
+&lt;&lt;
+</literal>
+and
+<literal>
+>>
+</literal>
+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
+<literal>int</literal>;
+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.
+<literallayout> 
+<emphasis>shift-expression:
+        expression &lt;&lt; expression
+        expression >> expression</emphasis>
+</literallayout>
+</para><para>
+The value of
+<literal>
+E1&lt;&lt;E2
+</literal>
+is
+<literal>
+E1
+</literal>
+(interpreted as a bit
+pattern) left-shifted
+<literal>
+E2
+</literal>
+bits.
+Vacated bits are 0 filled.
+The value of
+<literal>
+E1>>E2
+</literal>
+is
+<literal>
+E1
+</literal>
+right-shifted
+<literal>
+E2
+</literal>
+bit positions.
+The right shift is guaranteed to be logical
+(0 fill)
+if
+<literal>
+E1
+</literal>
+is
+<literal>unsigned</literal>;
+otherwise, it may be
+arithmetic.
+</para></sect2>
+<sect2><title>Relational Operators</title>
+<para>
+The relational operators group left to right. 
+<literallayout> 
+<emphasis>relational-expression:
+        expression &lt; expression
+        expression > expression
+        expression &lt;= expression
+        expression >= expression</emphasis>
+</literallayout>
+</para><para>
+The operators
+<literal>
+&lt;
+</literal>
+(less than),
+<literal>
+>
+</literal>
+(greater than), <literal>&lt;=</literal>
+(less than
+or equal to), and
+<literal>
+>=
+</literal>
+(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
+<literal>int</literal>.
+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.
+</para></sect2>
+<sect2><title>Equality Operators</title>
+<para>
+<literallayout> 
+<emphasis>equality-expression:
+        expression == expression
+        expression != expression</emphasis>
+</literallayout>
+</para><para>
+The
+<literal>
+==
+</literal>
+(equal to) and the
+<literal>
+!=
+</literal>
+(not equal to) operators
+are exactly analogous to the relational
+operators except for their lower
+precedence.
+(Thus
+<literal>
+a&lt;b\ ==\ c&lt;d
+</literal>
+is 1 whenever
+<literal>
+a&lt;b
+</literal>
+and
+<literal>
+c&lt;d
+</literal>
+have the same truth value).
+</para><para>
+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.
+</para></sect2>
+<sect2><title>Bitwise AND Operator</title>
+<para>
+<literallayout> 
+<emphasis>and-expression:
+        expression &amp; expression</emphasis>
+</literallayout>
+</para><para>
+The
+<literal>
+&amp;
+</literal>
+operator is associative,
+and expressions involving
+<literal>
+&amp;
+</literal>
+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.
+</para></sect2>
+<sect2><title>Bitwise Exclusive OR Operator</title>
+<literallayout> 
+<emphasis>exclusive-or-expression:
+        expression ^ expression</emphasis>
+</literallayout>
+<para>
+The
+<literal>
+^
+</literal>
+operator is associative,
+and expressions involving
+<literal>
+^
+</literal>
+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.
+</para></sect2>
+<sect2><title>Bitwise Inclusive OR Operator</title>
+<literallayout> 
+<emphasis>inclusive-or-expression:
+        expression | expression</emphasis>
+</literallayout>
+<para>
+The
+<literal>
+|
+</literal>
+operator is associative,
+and expressions involving
+<literal>
+|
+</literal>
+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.
+</para></sect2>
+<sect2><title>Logical AND Operator</title>
+<literallayout> 
+<emphasis>logical-and-expression:
+        expression &amp;&amp; expression</emphasis>
+</literallayout>
+<para>
+The
+<literal>
+&amp;&amp;
+</literal>
+operator groups left to right.
+It returns 1 if both its operands
+evaluate to nonzero, 0 otherwise.
+Unlike
+<literal>&amp;</literal>,
+<literal>
+&amp;&amp;
+</literal>
+guarantees left to right
+evaluation; moreover, the second operand is not evaluated
+if the first operand is 0.
+</para><para>
+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
+<literal>int</literal>.
+</para></sect2>
+<sect2><title>Logical OR Operator</title>
+<literallayout> 
+<emphasis>logical-or-expression:
+        expression || expression</emphasis>
+</literallayout>
+<para>
+The
+<literal>
+||
+</literal>
+operator groups left to right.
+It returns 1 if either of its operands
+evaluates to nonzero, 0 otherwise.
+Unlike
+<literal>|</literal>,
+<literal>
+||
+</literal>
+guarantees left to right evaluation; moreover,
+the second operand is not evaluated
+if the value of the first operand is nonzero.
+</para><para>
+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
+<literal>int</literal>.
+</para></sect2>
+<sect2><title>Conditional Operator</title>
+<literallayout> 
+<emphasis>conditional-expression:
+        expression ? expression : expression</emphasis>
+</literallayout>
+<para>
+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.
+</para></sect2>
+<sect2><title>Assignment Operators</title>
+<para>
+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.
+<literallayout> 
+<emphasis>assignment-expression:
+        lvalue = expression
+        lvalue += expression
+        lvalue -= expression
+        lvalue *= expression
+        lvalue /= expression
+        lvalue %= expression
+        lvalue >>= expression
+        lvalue &lt;&lt;= expression
+        lvalue &amp;= expression
+        lvalue ^= expression
+        lvalue |= expression</emphasis>
+</literallayout>
+</para><para>
+In the simple assignment with
+<literal>=</literal>,
+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.
+</para><para>
+The behavior of an expression
+of the form
+<literal>E1</literal> <emphasis>op</emphasis> = <literal>E2</literal>
+may be inferred by
+taking it as equivalent to
+<literal>E1 = E1</literal> <emphasis>op</emphasis> (<literal>E2</literal>);
+however,
+<literal>
+E1
+</literal>
+is evaluated only once.
+In
+<literal>
++=
+</literal>
+and
+<literal>-=</literal>,
+the left operand may be a pointer; in which case, the (integral) right
+operand is converted as explained
+in <quote>Additive Operators.</quote>
+All right operands and all nonpointer left operands must
+have arithmetic type.
+</para></sect2>
+<sect2><title>Comma Operator</title>
+<literallayout> 
+<emphasis>comma-expression:
+        expression , expression</emphasis>
+</literallayout>
+<para>
+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 <quote>Primary Expressions</quote>) and lists
+of initializers (see <quote>Initialization</quote> under <quote>DECLARATIONS</quote>),
+the comma operator as described in this subpart
+can only appear in parentheses. For example,
+<literallayout> 
+<literal>f(a, (t=3, t+2), c)</literal>
+</literallayout>
+has three arguments, the second of which has the value 5.
+</para></sect2></sect1>
+<sect1><title>
+Declarations
+</title><para>
+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
+<literallayout> 
+<emphasis>declaration:
+        decl-specifiers declarator-list<subscript>opt</subscript> ;</emphasis>
+</literallayout>
+</para><para> 
+The declarators in the declarator-list
+contain the identifiers being declared.
+The decl-specifiers
+consist of a sequence of type and storage class specifiers.
+<literallayout> 
+<emphasis>decl-specifiers:
+        type-specifier decl-specifiers<subscript>opt</subscript>
+        sc-specifier decl-specifiers<subscript>opt</subscript></emphasis>
+</literallayout>
+</para><para> 
+The list must be self-consistent in a way described below.
+</para>
+<sect2><title>Storage Class Specifiers</title>
+<para>
+The sc-specifiers are:
+<literallayout> 
+<emphasis>sc-specifier:</emphasis><literal>
+        auto
+        static
+        extern
+        register
+        typedef</literal>
+</literallayout>
+</para><para> 
+The
+<literal>typedef</literal>
+specifier does not reserve storage
+and is called a <quote>storage class specifier</quote> only for syntactic convenience.
+See <quote>Typedef</quote> for more information.
+The meanings of the various storage classes were discussed in <quote>Names.</quote>
+</para><para>
+The
+<literal>auto</literal>,
+<literal>static</literal>,
+and
+<literal>register</literal>
+declarations also serve as definitions
+in that they cause an appropriate amount of storage to be reserved.
+In the
+<literal>extern</literal>
+case,
+there must be an external definition (see <quote>External Definitions</quote>)
+for the given identifiers
+somewhere outside the function in which they are declared.
+</para><para>
+A
+<literal>register</literal>
+declaration is best thought of as an
+<literal>auto</literal>
+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
+<literal>int</literal>
+or pointer.
+One other restriction applies to register variables:
+the address-of operator
+<literal>
+&amp;
+</literal>
+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.
+</para><para>
+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
+<literal>auto</literal>
+inside a function,
+<literal>extern</literal>
+outside.
+Exception:
+functions are never automatic.
+</para></sect2>
+<sect2><title>Type Specifiers</title>
+<para>
+The type-specifiers are
+<literallayout> 
+<emphasis>type-specifier:</emphasis>
+<literal>char
+        short
+        int
+        long
+        unsigned
+        float
+        double</literal>
+        <emphasis>struct-or-union-specifier
+        typedef-name</emphasis>
+</literallayout>
+</para><para> 
+At most one of the words <literal>long</literal> or <literal>short</literal>
+may be specified in conjunction with <literal>int</literal>;
+the meaning is the same as if <literal>int</literal> were not mentioned.
+The word <literal>long</literal> may be specified in conjunction with
+<literal>float</literal>;
+the meaning is the same as <literal>double</literal>.
+The word <literal>unsigned</literal> may be specified alone, or
+in conjunction with <literal>int</literal> or any of its short
+or long varieties, or with <literal>char</literal>.
+</para><para>
+Otherwise, at most on type-specifier may be
+given in a declaration.
+In particular, adjectival use of <literal>long</literal>,
+<literal>short</literal>, or <literal>unsigned</literal> is not permitted
+with <literal>typedef</literal> names.
+If the type-specifier is missing from a declaration,
+it is taken to be <literal>int</literal>.
+</para><para>
+Specifiers for structures, unions, and enumerations are discussed in
+<quote>Structure, Union, and Enumeration Declarations.</quote>
+Declarations with
+<literal>
+typedef
+</literal>
+names are discussed in <quote>Typedef.</quote>
+</para></sect2>
+<sect2><title>Declarators</title>
+<para>
+The declarator-list appearing in a declaration
+is a comma-separated sequence of declarators,
+each of which may have an initializer.
+<literallayout> 
+<emphasis>declarator-list:
+        init-declarator
+        init-declarator , declarator-list</emphasis>
+</literallayout>
+<literallayout> 
+<emphasis>init-declarator:
+        declarator initializer<subscript>opt</subscript></emphasis>
+</literallayout>
+</para><para> 
+Initializers are discussed in <quote>Initialization</quote>.
+The specifiers in the declaration
+indicate the type and storage class of the objects to which the
+declarators refer.
+Declarators have the syntax:
+<literallayout> 
+<emphasis>declarator:
+        identifier
+        ( declarator )
+        * declarator
+        declarator ()
+        declarator [ constant-expression<subscript>opt</subscript> ]</emphasis>
+</literallayout>
+</para><para> 
+The grouping is
+the same as in expressions.
+</para></sect2>
+<sect2><title>Meaning of Declarators</title>
+<para>
+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.
+</para><para>
+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.
+</para><para>
+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.
+</para><para>
+Now imagine a declaration
+<literallayout> 
+<literal>T D1</literal>
+</literallayout>
+where
+<literal>
+T
+</literal>
+is a type-specifier (like
+<literal>int</literal>,
+etc.)
+and
+<literal>
+D1
+</literal>
+is a declarator.
+Suppose this declaration makes the identifier have type
+<quote>...
+<literal>
+T
+</literal>
+,</quote>
+where the <quote>...</quote> is empty if
+<literal>
+D1
+</literal>
+is just a plain identifier
+(so that the type of
+<literal>
+x
+</literal>
+in
+<quote><literal>int x</literal></quote>
+is just
+<literal>int</literal>).
+Then if
+<literal>
+D1
+</literal>
+has the form
+<literallayout> 
+<literal>*D</literal>
+</literallayout>
+the type of the contained identifier is
+<quote>... pointer to
+<literal>
+T
+</literal>
+\&amp;.</quote>
+</para><para>
+If
+<literal>
+D1
+</literal>
+has the form
+<literallayout> 
+<literal>D()</literal>
+</literallayout>
+then the contained identifier has the type
+<quote>... function returning
+<literal>T</literal>.</quote>
+If
+<literal>
+D1
+</literal>
+has the form
+<literallayout> 
+<literal>D[</literal><emphasis>constant-expression</emphasis><literal>]</literal>
+</literallayout>
+or
+<literallayout> 
+<literal>D[]</literal>
+</literallayout>
+then the contained identifier has type
+<quote>... array of
+<literal>T</literal>.</quote>
+In the first case, the constant
+expression
+is an expression
+whose value is determinable at compile time
+, whose type is
+<literal>int</literal>,
+and whose value is positive.
+(Constant expressions are defined precisely in <quote>Constant Expressions.</quote>)
+When several <quote>array of</quote> 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.
+</para><para>
+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).
+</para><para>
+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.
+</para><para>
+As an example, the declaration
+<literallayout> 
+<literal>int i, *ip, f(), *fip(), (*pfi)();</literal>
+</literallayout>
+declares an integer
+<literal>i</literal>,
+a pointer
+<literal>
+ip
+</literal>
+to an integer,
+a function
+<literal>
+f
+</literal>
+returning an integer,
+a function
+<literal>
+fip
+</literal>
+returning a pointer to an integer,
+and a pointer
+<literal>
+pfi
+</literal>
+to a function which
+returns an integer.
+It is especially useful to compare the last two.
+The binding of
+<literal>
+*fip()
+</literal>
+is
+<literal>
+*(fip())</literal>.
+The declaration suggests,
+and the same construction in an expression
+requires, the calling of a function
+<literal>
+fip</literal>.
+Using indirection through the (pointer) result
+to yield an integer.
+In the declarator
+<literal>(*pfi)()</literal>,
+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.
+</para><para>
+As another example,
+<literallayout> 
+<literal>float fa[17], *afp[17];</literal>
+</literallayout>
+declares an array of
+<literal>float</literal>
+numbers and an array of
+pointers to
+<literal>float</literal>
+numbers.
+Finally,
+<literallayout> 
+<literal>static int x3d[3][5][7];</literal>
+</literallayout>
+declares a static 3-dimensional array of integers,
+with rank 3&times;5&times;7.
+In complete detail,
+<literal>
+x3d
+</literal>
+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
+<literal>x3d</literal>,
+<literal>x3d[i]</literal>,
+<literal>x3d[i][j]</literal>,
+<literal>
+x3d[i][j][k]
+</literal>
+may reasonably appear in an expression.
+The first three have type <quote>array</quote>
+and the last has type
+<literal>int</literal>.
+</para></sect2>
+<sect2><title>Structure and Union Declarations</title>
+<para>
+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.
+<literallayout> 
+<emphasis>struct-or-union-specifier:
+        struct-or-union { struct-decl-list }
+        struct-or-union identifier { struct-decl-list }
+        struct-or-union identifier</emphasis>
+</literallayout>
+<literallayout> 
+<emphasis>struct-or-union:</emphasis><literal>
+        struct
+        union</literal>
+</literallayout>
+</para><para> 
+The
+struct-decl-list
+
+is a sequence of declarations for the members of the structure or union:
+<literallayout> 
+<emphasis>struct-decl-list:
+        struct-declaration
+        struct-declaration struct-decl-list</emphasis>
+</literallayout>
+<literallayout> 
+<emphasis>struct-declaration:
+        type-specifier struct-declarator-list ;</emphasis>
+</literallayout>
+<literallayout> 
+<emphasis>struct-declarator-list:
+        struct-declarator
+        struct-declarator , struct-declarator-list</emphasis>
+</literallayout>
+</para><para> 
+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
+<emphasis>
+field ;
+</emphasis>
+its length,
+a non-negative constant expression,
+is set off from the field name by a colon.
+<literallayout> 
+<emphasis>struct-declarator:
+        declarator
+        declarator : constant-expression
+        : constant-expression</emphasis>
+</literallayout>
+</para><para> 
+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.
+</para><para>
+Fields are assigned right to left
+on the
+PDP-11
+and
+VAX-11,
+left to right on the 3B 20.
+</para><para>
+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
+specifies alignment of the next field at an implementation dependant boundary.
+</para><para>
+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
+<literal>int</literal>
+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
+<literal>int</literal>
+are treated as containing a sign.
+For these reasons,
+it is strongly recommended that fields be declared as
+<literal>unsigned</literal>.
+In all implementations,
+there are no arrays of fields,
+and the address-of operator
+<literal>
+&amp;
+</literal>
+may not be applied to them, so that there are no pointers to
+fields.
+</para><para>
+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.
+</para><para>
+A structure or union specifier of the second form, that is, one of
+<literallayout> 
+        <literal>struct</literal> <emphasis>identifier { struct-decl-list </emphasis>}
+        <literal>union</literal> <emphasis>identifier { struct-decl-list </emphasis>}
+</literallayout>
+declares the identifier to be the
+<emphasis>
+structure tag
+</emphasis>
+(or union tag)
+of the structure specified by the list.
+A subsequent declaration may then use
+the third form of specifier, one of
+<literallayout> 
+        <literal>struct</literal> <emphasis>identifier</emphasis>
+        <literal>union</literal> <emphasis>identifier</emphasis>
+</literallayout>
+</para><para> 
+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.
+</para><para>
+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 <literal>typedef</literal> 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.
+</para><para>
+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.
+</para><para>
+A simple but important example of a structure declaration is
+the following binary tree structure:
+<literallayout> 
+<literal>struct tnode 
+{
+        char tword[20];
+        int count;
+        struct tnode *left;
+        struct tnode *right;
+};</literal>
+</literallayout>
+which contains an array of 20 characters, an integer, and two pointers
+to similar structures.
+Once this declaration has been given, the
+declaration
+<literallayout> 
+<literal>struct tnode s, *sp;</literal>
+</literallayout>
+declares
+<literal>
+s
+</literal>
+to be a structure of the given sort
+and
+<literal>
+sp
+</literal>
+to be a pointer to a structure
+of the given sort.
+With these declarations, the expression
+<literallayout> 
+<literal>sp->count</literal>
+</literallayout>
+refers to the
+<literal>
+count
+</literal>
+field of the structure to which
+<literal>
+sp
+</literal>
+points;
+<literallayout> 
+<literal>s.left</literal>
+</literallayout>
+refers to the left subtree pointer
+of the structure
+<literal>s</literal>;
+and
+<literallayout> 
+<literal>s.right->tword[0]</literal>
+</literallayout>
+refers to the first character of the
+<literal>
+tword
+</literal>
+member of the right subtree of
+<literal>
+s</literal>.
+</para><para>
+</para></sect2>
+<sect2><title>Initialization</title>
+<para>
+A declarator may specify an initial value for the
+identifier being declared.
+The initializer is preceded by
+<literal>
+= 
+</literal>
+and
+consists of an expression or a list of values nested in braces.
+<literallayout> 
+<emphasis>initializer:
+        = expression
+        = { initializer-list }
+        = { initializer-list , }</emphasis>
+</literallayout>
+<literallayout> 
+<emphasis>initializer-list:
+        expression
+        initializer-list , initializer-list</emphasis>
+        { <emphasis>initializer-list </emphasis>}
+        { <emphasis>initializer-list</emphasis> , }
+</literallayout>
+</para><para>
+All the expressions in an initializer
+for a static or external variable must be constant
+expressions, which are described in <quote>CONSTANT EXPRESSIONS</quote>,
+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.
+</para><para>
+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.
+</para><para>
+When an initializer applies to a
+<emphasis>
+scalar
+</emphasis>
+(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.
+</para><para>
+When the declared variable is an
+<emphasis>
+aggregate
+</emphasis>
+(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.
+</para><para>
+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.
+</para><para>
+A final abbreviation allows a
+<literal>char</literal>
+array to be initialized by a string.
+In this case successive characters of the string
+initialize the members of the array.
+</para><para>
+For example,
+<literallayout> 
+<literal>int x[] = { 1, 3, 5 };</literal>
+</literallayout>
+declares and initializes
+<literal>
+x
+</literal>
+as a one-dimensional array which has three members, since no size was specified
+and there are three initializers.
+<programlisting> 
+float y[4][3] = 
+{
+        { 1, 3, 5 },
+        { 2, 4, 6 },
+        { 3, 5, 7 },
+};
+</programlisting>
+is a completely-bracketed initialization:
+1, 3, and 5 initialize the first row of
+the array
+<literal>y[0]</literal>,
+namely
+<literal>y[0][0]</literal>,
+<literal>y[0][1]</literal>,
+and
+<literal>
+y[0][2]</literal>.
+Likewise, the next two lines initialize
+<literal>
+y[1]
+</literal>
+and
+<literal>
+y[2]</literal>.
+The initializer ends early and therefore
+<literal>
+y[3]
+</literal>
+is initialized with 0.
+Precisely, the same effect could have been achieved by
+<literallayout> 
+<literal>float y[4][3] = 
+{
+        1, 3, 5, 2, 4, 6, 3, 5, 7
+};</literal>
+</literallayout>
+</para><para> 
+The initializer for
+<literal>
+y
+</literal>
+begins with a left brace but that for
+<literal>
+y[0]
+</literal>
+does not;
+therefore, three elements from the list are used.
+Likewise, the next three are taken successively for
+<literal>
+y[1]
+</literal>
+and
+<literal>
+y[2]</literal>.
+Also,
+<literallayout> 
+<literal>float y[4][3] = 
+{
+        { 1 }, { 2 }, { 3 }, { 4 }
+};</literal>
+</literallayout>
+initializes the first column of
+<literal>
+y
+</literal>
+(regarded as a two-dimensional array)
+and leaves the rest 0.
+</para><para>
+Finally,
+<literallayout> 
+<literal>char msg[] = "Syntax error on line %s\n";</literal>
+</literallayout>
+shows a character array whose members are initialized
+with a string.
+</para></sect2>
+<sect2><title>Type Names</title>
+<para>
+In two contexts (to specify type conversions explicitly
+by means of a cast
+and as an argument of
+<literal>sizeof</literal>),
+it is desired to supply the name of a data type.
+This is accomplished using a <quote>type name</quote>, which in essence
+is a declaration for an object of that type which omits the name of
+the object.
+<literallayout> 
+<emphasis>type-name:
+        type-specifier abstract-declarator</emphasis>
+</literallayout>
+<literallayout> 
+<emphasis>abstract-declarator:
+        empty
+        ( abstract-declarator )
+        * abstract-declarator
+        abstract-declarator ()
+        abstract-declarator</emphasis> [ <emphasis>constant-expression<subscript>opt</subscript> </emphasis>]
+</literallayout>
+</para><para> 
+To avoid ambiguity,
+in the construction
+<literallayout> 
+        <emphasis>( abstract-declarator </emphasis>)
+</literallayout>
+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,
+<programlisting> 
+int
+int *
+int *[3]
+int (*)[3]
+int *()
+int (*)()
+int (*[3])()
+</programlisting>
+name respectively the types <quote>integer,</quote> <quote>pointer to integer,</quote>
+<quote>array of three pointers to integers,</quote>
+<quote>pointer to an array of three integers,</quote>
+<quote>function returning pointer to integer,</quote>
+<quote>pointer to function returning an integer,</quote>
+and <quote>array of three pointers to functions returning an integer.</quote>
+</para></sect2>
+<sect2><title>Typedef</title>
+<para>
+Declarations whose <quote>storage class</quote> is
+<literal>typedef</literal>
+do not define storage but instead
+define identifiers which can be used later
+as if they were type keywords naming fundamental
+or derived types.
+<literallayout> 
+<emphasis>typedef-name:</emphasis>
+        <emphasis>identifier</emphasis>
+</literallayout>
+</para><para> 
+Within the scope of a declaration involving
+<literal>typedef</literal>,
+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 <quote>Meaning of Declarators.</quote>
+For example,
+after
+<programlisting> 
+typedef int MILES, *KLICKSP;
+typedef struct { double re, im; } complex;
+</programlisting>
+the constructions
+<literallayout> 
+<literal>MILES distance;
+extern KLICKSP metricp;
+complex z, *zp;</literal>
+</literallayout>
+are all legal declarations; the type of
+<literal>
+distance
+</literal>
+is
+<literal>int</literal>,
+that of
+<literal>
+metricp
+</literal>
+is <quote>pointer to <literal>int</literal>, </quote>
+and that of
+<literal>
+z
+</literal>
+is the specified structure.
+The
+<literal>
+zp
+</literal>
+is a pointer to such a structure.
+</para><para>
+The
+<literal>typedef</literal>
+does not introduce brand-new types, only synonyms for
+types which could be specified in another way.
+Thus
+in the example above
+<literal>
+distance
+</literal>
+is considered to have exactly the same type as
+any other
+<literal>int</literal>
+object.
+</para></sect2></sect1>
+<sect1><title>
+Statements
+</title><para>
+Except as indicated, statements are executed in sequence.
+</para>
+<sect2><title>Expression Statement</title>
+<para>
+Most statements are expression statements, which have
+the form
+<literallayout> 
+<emphasis>expression </emphasis>;
+</literallayout>
+</para><para> 
+Usually expression statements are assignments or function
+calls.
+</para></sect2>
+<sect2><title>Compound Statement or Block</title>
+<para>
+So that several statements can be used where one is expected,
+the compound statement (also, and equivalently, called <quote>block</quote>) is provided:
+<literallayout> 
+<emphasis>compound-statement:
+        { declaration-list<subscript>opt</subscript> statement-list<subscript>opt</subscript> }</emphasis>
+</literallayout>
+<literallayout> 
+<emphasis>declaration-list:
+        declaration
+        declaration declaration-list</emphasis>
+</literallayout>
+<literallayout> 
+<emphasis>statement-list:
+        statement
+        statement statement-list</emphasis>
+</literallayout>
+</para><para> 
+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.
+</para><para>
+Any initializations of
+<literal>auto</literal>
+or
+<literal>register</literal>
+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
+<literal>static</literal>
+variables are performed only once when the program
+begins execution.
+Inside a block,
+<literal>extern</literal>
+declarations do not reserve storage
+so initialization is not permitted.
+</para></sect2>
+<sect2><title>Conditional Statement</title>
+<para>
+The two forms of the conditional statement are
+<literallayout> 
+<literal>if</literal> ( <emphasis>expression</emphasis> ) <emphasis>statement</emphasis>
+<literal>if</literal> ( <emphasis>expression</emphasis> ) <emphasis>statement</emphasis> <literal>else</literal> <emphasis>statement</emphasis>
+</literallayout>
+</para><para> 
+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 <quote>else</quote> ambiguity is resolved by connecting
+an
+<literal>
+else
+</literal>
+with the last encountered
+<literal>else</literal>-less
+<literal>
+if</literal>.
+</para></sect2>
+<sect2><title>While Statement</title>
+<para>
+The
+<literal>
+while
+</literal>
+statement has the form
+<literallayout> 
+<literal>while</literal> ( <emphasis>expression</emphasis> ) <emphasis>statement</emphasis>
+</literallayout>
+</para><para>
+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.
+</para></sect2>
+<sect2><title>Do Statement</title>
+<para>
+The
+<literal>
+do
+</literal>
+statement has the form
+<literallayout> 
+<literal>do</literal> <emphasis>statement</emphasis>  <literal>while</literal> ( <emphasis>expression </emphasis>) ;
+</literallayout>
+</para><para>
+The substatement is executed repeatedly until
+the value of the expression becomes 0.
+The test takes place after each execution of the
+statement.
+</para></sect2>
+<sect2><title>For Statement</title>
+<para>
+The
+<literal>
+for
+</literal>
+statement has the form:
+<literallayout>  
+<literal>for</literal><emphasis> ( exp-1<subscript>opt</subscript> ; exp-2<subscript>opt</subscript> ; exp-3<subscript>opt</subscript> ) statement</emphasis>
+</literallayout>
+</para><para>
+Except for the behavior of <literal>continue</literal>,
+this statement is equivalent to
+<literallayout> 
+<emphasis>exp-1 </emphasis>;
+<literal>while</literal> ( <emphasis>exp-2\ ) </emphasis>
+{
+        <emphasis>statement
+        exp-3 ;</emphasis>
+}
+</literallayout>
+</para><para>
+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.
+</para><para>
+Any or all of the expressions may be dropped.
+A missing
+<emphasis>
+exp-2
+</emphasis>
+makes the
+implied
+<literal>
+while
+</literal>
+clause equivalent to
+<literal>while(1)</literal>;
+other missing expressions are simply
+dropped from the expansion above.
+</para></sect2>
+<sect2><title>Switch Statement</title>
+<para>
+The
+<literal>
+switch
+</literal>
+statement causes control to be transferred
+to one of several statements depending on
+the value of an expression.
+It has the form
+<literallayout> 
+<literal>switch</literal> ( <emphasis>expression</emphasis> ) <emphasis>statement</emphasis>
+</literallayout>
+</para><para>
+The usual arithmetic conversion is performed on the
+expression, but the result must be
+<literal>int</literal>.
+The statement is typically compound.
+Any statement within the statement
+may be labeled with one or more case prefixes
+as follows:
+<literallayout> 
+<literal>case</literal> <emphasis>constant-expression </emphasis>:
+</literallayout>
+where the constant
+expression
+must be
+<literal>int</literal>.
+No two of the case constants in the same switch
+may have the same value.
+Constant expressions are precisely defined in <quote>CONSTANT EXPRESSIONS.</quote>
+</para><para>
+There may also be at most one statement prefix of the
+form
+<literallayout> 
+<literal>default :</literal>
+</literallayout>
+</para><para>
+When the
+<literal>
+switch
+</literal>
+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
+<literal>default</literal>,
+prefix, control
+passes to the prefixed
+statement.
+If no case matches and if there is no
+<literal>default</literal>,
+then
+none of the statements in the
+switch is executed.
+</para><para>
+The prefixes
+<literal>
+case
+</literal>
+and
+<literal>
+default
+</literal>
+do not alter the flow of control,
+which continues unimpeded across such prefixes.
+To exit from a switch, see
+<quote>Break Statement.</quote>
+</para><para>
+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.
+</para></sect2>
+<sect2><title>Break Statement</title>
+<para>
+The statement
+<literallayout> 
+<literal>break ;</literal>
+</literallayout>
+causes termination of the smallest enclosing
+<literal>while</literal>,
+<literal>do</literal>,
+<literal>for</literal>,
+or
+<literal>switch</literal>
+statement;
+control passes to the
+statement following the terminated statement.
+</para></sect2>
+<sect2><title>Continue Statement</title>
+<para>
+The statement
+<literallayout> 
+<literal>continue ;</literal>
+</literallayout>
+causes control to pass to the loop-continuation portion of the
+smallest enclosing
+<literal>while</literal>,
+<literal>do</literal>,
+or
+<literal>for</literal>
+statement; that is to the end of the loop.
+More precisely, in each of the statements
+<informaltable frame="none">
+<tgroup cols="3">
+<colspec colwidth="2in"/>
+<colspec colwidth="2in"/>
+<colspec colwidth="2in"/>
+<tbody>
+<row>
+  <entry>while (...) {</entry>
+  <entry>do {</entry>
+  <entry>for (...) {</entry>
+</row>
+<row>
+  <entry>statement ;</entry>
+  <entry>statement ;</entry>
+  <entry>statement ;</entry>
+</row>
+<row>
+  <entry>contin: ;</entry>
+  <entry>     contin: ;</entry>
+  <entry>     contin: ;</entry>
+</row>
+<row>
+  <entry>}</entry>
+  <entry>} while (...);</entry>
+  <entry>}</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+a
+<literal>
+continue
+</literal>
+is equivalent to
+<literal>
+goto\ contin</literal>.
+(Following the
+<literal>
+contin:
+</literal>
+is a null statement, see <quote>Null Statement</quote>.)
+</para></sect2>
+<sect2><title>Return Statement</title>
+<para>
+A function returns to its caller by means of
+the
+<literal>
+return
+</literal>
+statement which has one of the
+forms
+<literallayout> 
+<literal>return ;
+return </literal><emphasis>expression </emphasis>;
+</literallayout>
+</para><para>
+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.
+</para></sect2>
+<sect2><title>Goto Statement</title>
+<para>
+Control may be transferred unconditionally by means of
+the statement
+<literallayout> 
+<literal>goto</literal> <emphasis>identifier </emphasis>;
+</literallayout>
+</para><para>
+The identifier must be a label
+(see <quote>Labeled Statement</quote>)
+located in the current function.
+</para></sect2>
+<sect2><title>Labeled Statement</title>
+<para>
+Any statement may be preceded by
+label prefixes of the form
+<literallayout> 
+<emphasis>identifier </emphasis>:
+</literallayout>
+which serve to declare the identifier
+as a label.
+The only use of a label is as a target of a
+<literal>
+goto</literal>.
+The scope of a label is the current function,
+excluding any subblocks in which the same identifier has been redeclared.
+See <quote>SCOPE RULES.</quote>
+</para></sect2>
+<sect2><title>Null Statement</title>
+<para>
+The null statement has the form
+<literallayout>
+      <literal>;</literal>
+</literallayout>
+</para><para>
+A null statement is useful to carry a label just before the
+<literal>
+}
+</literal>
+of a compound statement or to supply a null
+body to a looping statement such as
+<literal>
+while</literal>.
+</para></sect2></sect1>
+<sect1><title>
+External Definitions
+</title><para>
+A C program consists of a sequence of external definitions.
+An external definition declares an identifier to
+have storage class
+<literal>extern</literal>
+(by default)
+or perhaps
+<literal>static</literal>,
+and
+a specified type.
+The type-specifier (see <quote>Type Specifiers</quote> in
+<quote>DECLARATIONS</quote>) may also be empty, in which
+case the type is taken to be
+<literal>int</literal>.
+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.
+</para>
+<sect2><title>External Function Definitions</title>
+<para>
+Function definitions have the form
+<literallayout>
+<emphasis>function-definition:
+        decl-specifiers<subscript>opt</subscript> function-declarator function-body</emphasis>
+</literallayout>
+</para><para>
+The only sc-specifiers
+allowed
+among the decl-specifiers
+are
+<literal>extern</literal>
+or
+<literal>static</literal>;
+see <quote>Scope of Externals</quote> in 
+<quote>SCOPE RULES</quote> for the distinction between them.
+A function declarator is similar to a declarator
+for a <quote>function returning ...</quote> except that
+it lists the formal parameters of
+the function being defined.
+<literallayout> 
+<emphasis>function-declarator:
+        declarator ( parameter-list<subscript>opt</subscript> )</emphasis>
+</literallayout>
+<literallayout> 
+<emphasis>parameter-list:
+        identifier
+        identifier , parameter-list</emphasis>
+</literallayout>
+</para><para>
+The function-body
+has the form
+<literallayout> 
+<emphasis>function-body:
+        declaration-list<subscript>opt</subscript> compound-statement</emphasis>
+</literallayout>
+</para><para>
+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
+<literal>int</literal>.
+The only storage class which may be specified is
+<literal>register</literal>;
+if it is specified, the corresponding actual parameter
+will be copied, if possible, into a register
+at the outset of the function.
+</para><para>
+A simple example of a complete function definition is
+<literallayout> 
+<literal>int max(a, b, c)
+        int a, b, c;
+{
+        int m;
+
+        m = (a > b) ? a : b;
+        return((m > c) ? m : c);
+}</literal>
+</literallayout>
+</para><para>
+Here
+<literal>int</literal>
+is the type-specifier;
+<literal>
+max(a, b, c)
+</literal>
+is the function-declarator;
+<literal>
+int a, b, c;
+</literal>
+is the declaration-list for
+the formal
+parameters;
+<literal>{ ... }</literal>
+is the
+block giving the code for the statement.
+</para><para>
+The C program converts all
+<literal>float</literal>
+actual parameters
+to
+<literal>double</literal>,
+so formal parameters declared
+<literal>float</literal>
+have their declaration adjusted to read
+<literal>double</literal>.
+All <literal>char</literal> and <literal>short</literal> formal parameter
+declarations are similarly adjusted
+to read <literal>int</literal>.
+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 <quote>array of ...</quote>
+are adjusted to read <quote>pointer to ....</quote>
+</para></sect2>
+<sect2><title>External Data Definitions</title>
+<para>
+An external data definition has the form
+<literallayout> 
+<emphasis>data-definition:
+        declaration</emphasis>
+</literallayout>
+</para><para>
+The storage class of such data may be
+<literal>extern</literal>
+(which is the default)
+or
+<literal>static</literal>
+but not
+<literal>auto</literal>
+or
+<literal>register</literal>.
+</para></sect2></sect1>
+<sect1><title>
+Scope Rules
+</title><para>
+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.
+</para><para>
+Therefore, there are two kinds of scopes to consider:
+first, what may be called the
+<emphasis>lexical scope</emphasis>
+of an identifier, which is essentially the
+region of a program during which it may
+be used without drawing <quote>undefined identifier</quote>
+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.
+</para>
+<sect2><title>Lexical Scope</title>
+<para>
+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.
+</para><para>
+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.
+</para><para>
+Remember also (see <quote>Structure, Union, and Enumeration Declarations</quote> in
+<quote>DECLARATIONS</quote>) 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 <literal>enum</literal> constants are in the same
+class as ordinary variables and follow the same scope rules.
+The
+<literal>typedef</literal>
+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:
+<programlisting> 
+typedef float distance;
+...
+{
+     auto int distance;
+     ...
+}
+</programlisting>
+</para><para>
+The
+<literal>int</literal>
+must be present in the second declaration,
+or it would be taken to be
+a declaration with no declarators and type
+<literal>
+distance</literal>.
+</para></sect2>
+<sect2><title>Scope of Externals</title>
+<para>
+If a function refers to an identifier declared to be
+<literal>extern</literal>,
+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.
+</para><para>
+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 <literal>extern</literal> does not
+change the meaning of an external declaration.
+</para><para>
+In restricted environments, the use of the <literal>extern</literal>
+storage class takes on an additional meaning.
+In these environments, the explicit appearance of the
+<literal>extern</literal> 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 <literal>extern</literal>)
+in the set of files and libraries
+comprising a mult-file program.
+</para><para>
+Identifiers declared
+<literal>static</literal>
+at the top level in external definitions
+are not visible in other files.
+Functions may be declared
+<literal>static</literal>.
+</para></sect2></sect1>
+<sect1><title>
+Compiler Control Lines
+</title><para>
+The C compiler contains a preprocessor capable
+of macro substitution, conditional compilation,
+and inclusion of named files.
+Lines beginning with
+<literal>
+#
+</literal>
+communicate
+with this preprocessor.
+There may be any number of blanks and horizontal tabs
+between the <literal>#</literal> 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.
+</para>
+<sect2><title>Token Replacement</title>
+<para>
+A compiler-control line of the form
+<literallayout> 
+<literal>#define</literal> <emphasis>identifier token-string<subscript>opt</subscript></emphasis>
+</literallayout>
+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
+<literallayout>
+<literal>#define</literal> <emphasis>identifier(identifier, ... )token-string<subscript>opt</subscript></emphasis>
+</literallayout>
+where there is no space between the first identifier
+and the
+<literal>(</literal>,
+is a macro definition with arguments.
+There may be zero or more formal parameters.
+Subsequent instances of the first identifier followed
+by a
+<literal>(</literal>,
+a sequence of tokens delimited by commas, and a
+<literal>)</literal>
+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.
+</para><para>
+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
+<literal>
+\
+</literal>
+at the end of the line to be continued.
+</para><para>
+This facility is most valuable for definition of <quote>manifest constants,</quote>
+as in
+<screen> 
+#define TABSIZE 100
+
+int table[TABSIZE];
+</screen>
+</para><para>
+A control line of the form
+<literallayout> 
+<literal>#undef</literal> <emphasis>identifier</emphasis>
+</literallayout>
+causes the
+identifier's preprocessor definition (if any) to be forgotten.
+</para><para>
+If a <literal>#define</literal>d identifier is the subject of a subsequent
+<literal>#define</literal> with no intervening <literal>#undef</literal>, 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.
+</para></sect2>
+<sect2><title>File Inclusion</title>
+<para>
+A compiler control line of
+the form
+<literallayout> 
+<literal>#include</literal><emphasis> &quot;filename</emphasis>&quot;
+</literallayout>
+causes the replacement of that
+line by the entire contents of the file
+<emphasis>
+filename</emphasis>.
+The named file is searched for first in the directory
+of the file containing the <literal>#include</literal>,
+and then in a sequence of specified or standard places.
+Alternatively, a control line of the form
+<literallayout> 
+<literal>#include</literal><emphasis> &lt;filename</emphasis>>
+</literallayout>
+searches only the specified or standard places
+and not the directory of the <literal>#include</literal>.
+(How the places are specified is not part of the language.)
+</para><para>
+<literal>#include</literal>s
+may be nested.
+</para></sect2>
+<sect2><title>Conditional Compilation</title>
+<para>
+A compiler control line of the form
+<literallayout> 
+<literal>#if</literal> <emphasis>constant-expression</emphasis>
+</literallayout>
+checks whether the constant expression evaluates to nonzero.
+(Constant expressions are discussed in <quote>CONSTANT EXPRESSIONS</quote>.
+A control line of the form
+<literallayout> 
+<literal>#ifdef </literal><emphasis>identifier</emphasis>
+</literallayout>
+checks whether the identifier is currently defined
+in the preprocessor; i.e., whether it has been the
+subject of a
+<literal>
+#define
+</literal>
+control line.
+It is equivalent to <literal>#ifdef(</literal><emphasis>identifier</emphasis><literal>)</literal>.
+A control line of the form
+<literallayout> 
+<literal>#ifndef </literal><emphasis>identifier</emphasis>
+</literallayout>
+checks whether the identifier is currently undefined
+in the preprocessor.
+It is equivalent to
+<literallayout>
+<literal>#if !defined(</literal><emphasis>identifier</emphasis><literal>)</literal>.
+</literallayout>
+</para><para>
+All three forms are followed by an arbitrary number of lines,
+possibly containing a control line
+<literallayout> 
+<literal>#else</literal>
+</literallayout>
+and then by a control line
+<literallayout> 
+<literal>#endif</literal>
+</literallayout>
+</para><para>
+If the checked condition is true,
+then any lines
+between
+<literal>
+#else
+</literal>
+and
+<literal>
+#endif
+</literal>
+are ignored.
+If the checked condition is false, then any lines between
+the test and a
+<literal>
+#else
+</literal>
+or, lacking a
+<literal>#else</literal>,
+the
+<literal>
+#endif 
+</literal>
+are ignored.
+</para><para>
+These constructions may be nested.
+</para></sect2>
+<sect2><title>Line Control</title>
+<para>
+For the benefit of other preprocessors which generate C programs,
+a line of the form
+<literallayout> 
+<literal>#line </literal><emphasis>constant identifier</emphasis>
+</literallayout>
+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 the identifier.
+If the identifier is absent, the remembered file name does not change.
+</para></sect2></sect1>
+<sect1><title>
+Implicit Declarations
+</title><para>
+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
+<literal>int</literal>;
+if a type but no storage class is indicated,
+the identifier is assumed to
+be
+<literal>auto</literal>.
+An exception to the latter rule is made for
+functions because
+<literal>auto</literal>
+functions do not exist.
+If the type of an identifier is <quote>function returning ...,</quote>
+it is implicitly declared to be
+<literal>extern</literal>.
+</para><para>
+In an expression, an identifier
+followed by
+<literal>
+(
+</literal>
+and not already declared
+is contextually
+declared to be <quote>function returning
+<literal>int</literal>.</quote>
+</para></sect1>
+<sect1><title>
+Types Revisited
+</title><para>
+This part summarizes the operations
+which can be performed on objects of certain types.
+</para>
+<sect2><title>Structures and Unions</title>
+<para>
+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.
+</para><para>
+In a reference
+to a structure or union member, the
+name on the right
+of the <literal>-></literal> or the <literal>.</literal>
+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.
+</para></sect2>
+<sect2><title>Functions</title>
+<para>
+There are only two things that
+can be done with a function <literal>m</literal>,
+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
+<programlisting> 
+int f();
+...
+g(f);
+</programlisting>
+</para><para>
+Then the definition of
+<literal>
+g
+</literal>
+might read
+<programlisting> 
+g(funcp)
+        int (*funcp)();
+{
+        ...
+        (*funcp)();
+        ...
+}
+</programlisting>
+</para><para>
+Notice that
+<literal>
+f
+</literal>
+must be declared
+explicitly in the calling routine since its appearance
+in
+<literal>
+g(f)
+</literal>
+was not followed by
+<literal>
+(.
+</literal>
+</para></sect2>
+<sect2><title>Arrays, Pointers, and Subscripting</title>
+<para>
+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
+<literal>[]</literal>
+is interpreted
+in such a way that
+<literal>E1[E2]</literal>
+is identical to
+<literal>*((E1)+E2))</literal>.
+Because of the conversion rules
+which apply to
+<literal>+</literal>,
+if
+<literal>E1</literal>
+is an array and
+<literal>E2</literal>
+an integer, then
+<literal>E1[E2]</literal>
+refers to the
+<literal>E2-th</literal>
+member of
+<literal>E1</literal>.
+Therefore,
+despite its asymmetric
+appearance, subscripting is a commutative operation.
+</para><para>
+A consistent rule is followed in the case of
+multidimensional arrays.
+If
+<literal>E</literal>
+is an
+<emphasis>n</emphasis>-dimensional
+array
+of rank
+i&times;j&times;...&times;k,
+then
+<literal>
+E
+</literal>
+appearing in an expression is converted to
+a pointer to an (n-1)-dimensional
+array with rank
+j&times;...&times;k.
+If the
+<literal>
+*
+</literal>
+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.
+</para><para>
+For example, consider
+<literallayout> 
+<literal>int x[3][5];</literal>
+</literallayout>
+</para><para>
+Here
+<literal>
+x
+</literal>
+is a 3&times;5 array of integers.
+When
+<literal>
+x
+</literal>
+appears in an expression, it is converted
+to a pointer to (the first of three) 5-membered arrays of integers.
+In the expression
+<literal>x[i]</literal>,
+which is equivalent to
+<literal>*(x+i)</literal>,
+<literal>
+x
+</literal>
+is first converted to a pointer as described;
+then
+<literal>
+i
+</literal>
+is converted to the type of
+<literal>x</literal>,
+which involves multiplying
+<literal>
+i
+</literal>
+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.
+</para><para>
+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.
+</para></sect2>
+<sect2><title>Explicit Pointer Conversions</title>
+<para>
+Certain conversions involving pointers are permitted
+but have implementation-dependent aspects.
+They are all specified by means of an explicit type-conversion
+operator, see <quote>Unary Operators</quote> under<quote>EXPRESSIONS</quote> and
+<quote>Type Names</quote>under <quote>DECLARATIONS.</quote>
+</para><para>
+A pointer may be converted to any of the integral types large
+enough to hold it.
+Whether an
+<literal>int</literal>
+or
+<literal>long</literal>
+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.
+</para><para>
+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.
+</para><para>
+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.
+</para><para>
+For example,
+a storage-allocation routine
+might accept a size (in bytes)
+of an object to allocate, and return a
+<literal>char</literal>
+pointer;
+it might be used in this way.
+<programlisting> 
+extern char *alloc();
+double *dp;
+
+dp = (double *) alloc(sizeof(double));
+*dp = 22.0 / 7.0;
+</programlisting>
+</para><para>
+The
+<function>alloc</function>
+must ensure (in a machine-dependent way)
+that its return value is suitable for conversion to a pointer to
+<literal>double</literal>;
+then the
+<emphasis>
+use
+</emphasis>
+of the function is portable.
+</para><para>
+The pointer
+representation on the
+PDP-11
+corresponds to a 16-bit integer and
+measures bytes.
+The
+<literal>char</literal>'s
+have no alignment requirements; everything else must have an even address.
+</para><para>
+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
+<literal>double</literal>
+quantities need be aligned only on even 4-byte boundaries.
+Aggregates are aligned on the strictest boundary required by
+any of their constituents.
+</para><para>
+The 3B 20 computer has 24-bit pointers placed into 32-bit quantities.
+Most objects are
+aligned on 4-byte boundaries. <literal>short</literal>s are aligned in all cases on
+2-byte boundaries. Arrays of characters, all structures,
+<literal>int</literal>s, <literal>long</literal>s, <literal>float</literal>s, and <literal>double</literal>s are aligned on 4-byte
+boundries; but structure members may be packed tighter.
+</para></sect2>
+<sect2><title>CONSTANT EXPRESSIONS</title>
+<para>
+In several places C requires expressions that evaluate to
+a constant:
+after
+<literal>case</literal>,
+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
+<literal>
+sizeof
+</literal>
+expressions, possibly
+connected by the binary operators
+<literallayout> 
++ - * / % &amp; | ^ &lt;&lt; >> == != &lt; > &lt;= >= &amp;&amp; ||
+</literallayout>
+or by the unary operators
+<literallayout> 
+-  ~
+</literallayout>
+or by the ternary operator
+<literallayout> 
+?:
+</literallayout>
+</para><para>
+Parentheses can be used for grouping
+but not for function calls.
+</para><para>
+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
+<literal>
+&amp;
+</literal>
+operator to external or static objects
+and to external or static arrays subscripted
+with a constant expression.
+The unary
+<literal>
+&amp;
+</literal>
+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.
+</para></sect2></sect1>
+<sect1><title>
+Portability Considerations
+</title><para>
+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.
+</para><para>
+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.
+</para><para>
+The number of
+<literal>register</literal>
+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
+<literal>register</literal>
+declarations are ignored.
+</para><para>
+Some difficulties arise only when
+dubious coding practices are used.
+It is exceedingly unwise to write programs
+that depend
+on any of these properties.
+</para><para>
+The order of evaluation of function arguments
+is not specified by the language.
+The order in which side effects take place
+is also unspecified.
+</para><para>
+Since character constants are really objects of type
+<literal>int</literal>,
+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.
+</para><para>
+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
+<literal>int</literal>
+pointer to a
+<literal>char</literal>
+pointer and inspecting the pointed-to storage)
+but must be accounted for when conforming to externally-imposed
+storage layouts.
+</para><para>
+The language accepted by the various compilers differs in minor details. Most
+notably, the current PDP-11 compiler will not initialize structures containing
+bitfields, and does not accept a few assignment operators in certain contexts where the
+value of the assignment is used.
+</para></sect1>
+<sect1><title>Anachronisms</title>
+<para>
+Since C is an evolving language, certain obsolete constructions may be
+found in older programs. Although most versions of the compiler support
+such anachronisms, ultimately they will disappear, leaving only a portability
+problem behind.
+</para>
+<para>
+Earlier versions of C used the form =op instead of op= for assignment
+operators. This leads to ambiguities, typified by:
+<screen>
+     x=-1
+</screen>
+which actually decrements x since the = and the - are adjacent, but which might
+easily be intended to assign -1 to x.
+</para>
+<para>
+The syntax of initializers has changed: previously, the equals sign that introduces
+and initializer was not present, so instead of
+<screen>
+     int x    = 1;
+</screen>
+one used
+<screen>
+     int x    1;
+</screen>
+The change was made because the initialization
+<screen>
+     int f  (1+2)
+</screen>
+resembles a function declaration closely enough to confuse the compilers.
+</para></sect1>
+<sect1><title>Syntax Summary</title>
+<para>
+This summary of C syntax is intended more for aiding comprehension
+than as an exact statement of the language.
+</para>
+<sect2><title>Expressions</title>
+<para>
+The basic expressions are:
+<literallayout> 
+     <emphasis>expression:
+             primary
+             * expression
+             &amp;lvalue
+             - expression
+             ! expression
+             ~ expression
+             ++ lvalue
+             --lvalue
+             lvalue ++
+             lvalue --</emphasis>
+             <literal>sizeof</literal><emphasis> expression</emphasis>
+             <literal>sizeof (</literal><emphasis>type-name</emphasis><literal>)</literal><emphasis>
+             ( type-name ) expression
+             expression binop expression
+             expression ? expression : expression
+             lvalue asgnop expression
+             expression , expression</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>primary:
+             identifier
+             constant
+             string
+             ( expression )
+             primary ( expression-list<subscript>opt</subscript> )
+             primary [ expression ]
+             primary . identifier
+             primary - identifier</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>lvalue:
+             identifier
+             primary [ expression ]
+             lvalue . identifier
+             primary - identifier
+             * expression
+             ( lvalue )</emphasis>
+</literallayout>
+</para><para>
+The primary-expression operators
+<literallayout> 
+     ()  []  .  -&lt;
+</literallayout>
+have highest priority and group left to right.
+The unary operators
+<literallayout> 
+     *  &amp;  -  !  ~  ++ -- <literal>sizeof</literal><emphasis>   ( type-name </emphasis>)
+</literallayout>
+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.
+<literallayout> 
+     <emphasis>binop:</emphasis>
+             *    /    %
+             +    -
+             >>   &lt;&lt;
+             &lt;    >    &lt;=    >=
+             ==   !=
+             &amp;
+             ^
+             |
+             &amp;&amp;
+             ||
+</literallayout>
+The conditional operator groups right to left.
+</para><para>
+Assignment operators all have the same
+priority and all group right to left.
+<literallayout> 
+     <emphasis>asgnop:</emphasis>
+             =  +=  -=  *=  /=  %=  >>=  &lt;&lt;=  &amp;=  ^=  |=
+</literallayout>
+</para><para>
+The comma operator has the lowest priority and groups left to right.
+</para></sect2>
+<sect2><title>Declarations</title>
+<para>
+<literallayout> 
+     <emphasis>declaration:
+             decl-specifiers init-declarator-list<subscript>opt</subscript> ;</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>decl-specifiers:
+             type-specifier decl-specifiers<subscript>opt</subscript>
+             sc-specifier decl-specifiers<subscript>opt</subscript></emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>sc-specifier:</emphasis><literal>
+             auto
+             static
+             extern
+             register
+             typedef</literal>
+</literallayout>
+<literallayout> 
+     <emphasis>type-specifier:</emphasis>
+     <literal>char
+             short
+             int
+             long
+             unsigned
+             float
+             double</literal>
+             <emphasis>struct-or-union-specifier
+             typedef-name</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>init-declarator-list:
+             init-declarator
+             init-declarator , init-declarator-list</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>init-declarator:
+             declarator initializer<subscript>opt</subscript></emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>declarator:
+             identifier
+             ( declarator )
+             * declarator
+             declarator ()
+             declarator [ constant-expression<subscript>opt</subscript> ]</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>struct-or-union-specifier:</emphasis><literal>
+             struct</literal><emphasis> { struct-decl-list }</emphasis><literal>
+             struct</literal> <emphasis>identifier { struct-decl-list }</emphasis><literal>
+             struct</literal> <emphasis>identifier</emphasis><literal>
+             union {</literal> <emphasis>struct-decl-list }</emphasis><literal>
+             union </literal><emphasis>identifier { struct-decl-list }</emphasis><literal>
+             union </literal><emphasis>identifier</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>struct-decl-list:
+             struct-declaration
+             struct-declaration struct-decl-list</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>struct-declaration:
+             type-specifier struct-declarator-list ;</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>struct-declarator-list:
+             struct-declarator
+             struct-declarator , struct-declarator-list</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>struct-declarator:
+             declarator
+             declarator : constant-expression
+             : constant-expression</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>initializer:
+             = expression
+             = { initializer-list }
+             = { initializer-list , }</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>initializer-list:
+             expression
+             initializer-list , initializer-list
+             { initializer-list }
+             { initializer-list , }</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>type-name:
+             type-specifier abstract-declarator</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>abstract-declarator:
+             empty
+             ( abstract-declarator )
+             * abstract-declarator
+             abstract-declarator ()
+             abstract-declarator [ constant-expression<subscript>opt</subscript> ]</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>typedef-name:
+             identifier</emphasis>
+</literallayout>
+</para></sect2>
+<sect2><title>Statements</title>
+<para>
+<literallayout> 
+     <emphasis>compound-statement:
+             { declaration-list<subscript>opt</subscript> statement-list<subscript>opt</subscript> }</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>declaration-list:
+             declaration
+             declaration declaration-list</emphasis>
+</literallayout>
+<literallayout> 
+     <emphasis>statement-list:
+             statement
+             statement statement-list</emphasis>
+</literallayout>
+<literallayout>  
+     <emphasis>statement:
+             compound-statement
+             expression ;</emphasis>
+             <literal>if</literal><emphasis> ( expression ) statement</emphasis>
+             <literal>if</literal><emphasis> ( expression ) statement</emphasis>  <literal>else</literal><emphasis> statement</emphasis>
+             <literal>while</literal><emphasis> ( expression ) statement</emphasis>
+             <literal>do</literal><emphasis> statement</emphasis>  <literal>while</literal><emphasis> ( expression ) ;</emphasis>
+             <literal>for</literal><emphasis> (exp<subscript>opt</subscript>'</emphasis><literal>;</literal><emphasis>exp<subscript>opt</subscript>'</emphasis><literal>;</literal><emphasis>exp<subscript>opt</subscript>'</emphasis><emphasis>) statement</emphasis>
+             <literal>switch</literal><emphasis> ( expression ) statement</emphasis>
+             <literal>case</literal><emphasis> constant-expression :  statement</emphasis>
+             <literal>default</literal><emphasis> : statement</emphasis>
+             <literal>break ;
+             continue ;
+             return ;
+             return</literal><emphasis> expression ;</emphasis>
+             <literal>goto</literal><emphasis> identifier ;
+             identifier : statement
+             ;</emphasis>
+</literallayout>
+</para></sect2>
+<sect2><title>External definitions</title>
+<para>
+<literallayout>
+     <emphasis>program:
+             external-definition
+             external-definition program</emphasis>
+</literallayout>
+<literallayout>
+     <emphasis>external-definition:
+             function-definition
+             data-definition</emphasis>
+</literallayout>
+<literallayout>
+     <emphasis>function-definition:
+             decl-specifier<subscript>opt</subscript> function-declarator function-body</emphasis>
+</literallayout>
+<literallayout>
+     <emphasis>function-declarator:
+             declarator ( parameter-list<subscript>opt</subscript> )</emphasis>
+</literallayout>
+<literallayout>
+     <emphasis>parameter-list:
+             identifier
+             identifier , parameter-list</emphasis>
+</literallayout>
+<literallayout>
+     <emphasis>function-body:
+             declaration-list<subscript>opt</subscript> compound-statement</emphasis>
+</literallayout>
+<literallayout>
+     <emphasis>data-definition:</emphasis>
+             <literal>extern</literal><emphasis> declaration</emphasis><literal> ;</literal>
+             <literal>static</literal><emphasis> declaration</emphasis><literal> ;</literal>
+</literallayout>
+</para></sect2>
+<sect2><title>Preprocessor</title>
+<literallayout>
+             <literal>#define</literal><replaceable> identifier token-string<subscript>opt</subscript></replaceable>
+             <literal>#define</literal><replaceable> identifier</replaceable><literal>(</literal><replaceable>identifier</replaceable><literal>,...)</literal><replaceable>token-string<subscript>opt</subscript></replaceable>
+             <literal>#undef</literal><replaceable> identifier</replaceable>
+             <literal>#include &quot;</literal><replaceable>filename</replaceable><literal>&quot;</literal>
+             #include &lt;<replaceable>filename</replaceable>&gt;
+             <literal>#if</literal><replaceable> constant-expression</replaceable>
+             <literal>#ifdef</literal><replaceable> identifier</replaceable>
+             <literal>#ifndef</literal><replaceable> identifier</replaceable>
+             <literal>#else</literal>
+             <literal>#endif</literal>
+             <literal>#line</literal> <replaceable>constant</replaceable> <replaceable>identifier</replaceable>
+</literallayout>
+</sect2>
+</sect1>
+</appendix>