Mercurial > hg > Members > kono > nitros9-code
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>"..."</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>"</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>±10<superscript>±38</superscript></entry> + <entry>±10<superscript>±38</superscript></entry> + <entry>±10<superscript>±38</superscript></entry> +</row> +<row> + <entry>double range</entry> + <entry>±10<superscript>±38</superscript></entry> + <entry>±10<superscript>±38</superscript></entry> + <entry>±10<superscript>±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>&</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 + & 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> +& +</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> +<< +</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 << expression + expression >> expression</emphasis> +</literallayout> +</para><para> +The value of +<literal> +E1<<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 < expression + expression > expression + expression <= expression + expression >= expression</emphasis> +</literallayout> +</para><para> +The operators +<literal> +< +</literal> +(less than), +<literal> +> +</literal> +(greater than), <literal><=</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<b\ ==\ c<d +</literal> +is 1 whenever +<literal> +a<b +</literal> +and +<literal> +c<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 & expression</emphasis> +</literallayout> +</para><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 +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 && expression</emphasis> +</literallayout> +<para> +The +<literal> +&& +</literal> +operator groups left to right. +It returns 1 if both its operands +evaluate to nonzero, 0 otherwise. +Unlike +<literal>&</literal>, +<literal> +&& +</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 <<= expression + lvalue &= 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> +& +</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> +\&.</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×5×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> +& +</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> "filename</emphasis>" +</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> <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×j×...×k, +then +<literal> +E +</literal> +appearing in an expression is converted to +a pointer to an (n-1)-dimensional +array with rank +j×...×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×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> ++ - * / % & | ^ << >> == != < > <= >= && || +</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> +& +</literal> +operator to external or static objects +and to external or static arrays subscripted +with a constant expression. +The unary +<literal> +& +</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 + &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> + () [] . -< +</literallayout> +have highest priority and group left to right. +The unary operators +<literallayout> + * & - ! ~ ++ -- <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> + * / % + + - + >> << + < > <= >= + == != + & + ^ + | + && + || +</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> + = += -= *= /= %= >>= <<= &= ^= |= +</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 "</literal><replaceable>filename</replaceable><literal>"</literal> + #include <<replaceable>filename</replaceable>> + <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>