The C Programming Language - Reference Manual Dennis M. Ritchie Bell Laboratories Murray Hill, New Jersey 07974 This manual is a reprint, with updates to the current C standard, from _T_h_e _C _P_r_o_g_r_a_m_m_i_n_g _L_a_n_g_u_a_g_e, by Brian W. Ker- nighan and Dennis M. Richie, Prentice-Hall, Inc., 1978. _1. _I_n_t_r_o_d_u_c_t_i_o_n This manual describes the C language on the DEC PDP- 11|-, the DEC VAX-11, and the AT&T 3B 20|=. 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 pro- perties of the hardware; the various compilers are generally quite compatible. _2. _L_e_x_i_c_a_l _C_o_n_v_e_n_t_i_o_n_s There are six classes of tokens - identifiers, key- words, constants, strings, operators, and other separators. Blanks, tabs, new-lines, and comments (collectively, ``white space'') as described below are ignored except as they serve to separate tokens. Some white space is required to separate otherwise adjacent identifiers, keywords, and con- stants. 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. __________________________ |- DEC PDP-11, and DEC VAX-11 are trademarks of Digital Equipment Corporation. |= 3B 20 is a trademark of AT&T. September 2, 1987 - 2 - _2._1. _C_o_m_m_e_n_t_s The characters /* introduce a comment which terminates with the characters */. Comments do not nest. _2._2. _I_d_e_n_t_i_f_i_e_r_s (_N_a_m_e_s) An identifier is a sequence of letters and digits. The first character must be a letter. The underscore (_) 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 charac- ters 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: PDP-11 7 characters, 2 cases VAX-11 >100 characters, 2 cases AT&T 3B 20 >100 characters, 2 cases _2._3. _K_e_y_w_o_r_d_s The following identifiers are reserved for use as key- words and may not be used otherwise: auto do for return typedef break double goto short union case else if sizeof unsigned char enum int static void continue external long structwhile default float register switch Some implementations also reserve the words _f_o_r_t_r_a_n, _a_s_m, _g_f_l_o_a_t, _h_f_l_o_a_t and _q_u_a_d _2._4. _C_o_n_s_t_a_n_t_s There are several kinds of constants. Each has a type; an introduction to types is given in ``NAMES.'' Hardware characteristics that affect sizes are summarized in ``Hardware Characteristics'' under ``LEXICAL CONVENTIONS.'' _2._4._1. _I_n_t_e_g_e_r _C_o_n_s_t_a_n_t_s An integer constant consisting of a sequence of digits is taken to be octal if it begins with _0 (digit zero). An octal constant consists of the digits 0 through 7 only. A sequence of digits preceded by _0_x or _0_X (digit zero) is taken to be a hexadecimal integer. The hexadecimal digits September 2, 1987 - 3 - include _a or _A through _f or _F 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 long; an octal or hex con- stant which exceeds the largest unsigned machine integer is likewise taken to be _l_o_n_g. Otherwise, integer constants are int. _2._4._2. _E_x_p_l_i_c_i_t _L_o_n_g _C_o_n_s_t_a_n_t_s A decimal, octal, or hexadecimal integer constant immediately followed by _l (letter ell) or _L is a long con- stant. As discussed below, on some machines integer and long values may be considered identical. _2._4._3. _C_h_a_r_a_c_t_e_r _C_o_n_s_t_a_n_t_s A character constant is a character enclosed in single quotes, as in 'x'. The value of a character constant is the numerical value of the character in the machine's character set. Certain nongraphic characters, the single quote (') and the backslash (\), may be represented according to the fol- lowing table of escape sequences: new-line NL (LF) \n horizontal tab HT \t vertical tab VT \v backspace BS \b carriage return CR \r form feed FF \f backslash \ \\ single quote ' \' bit pattern _d_d_d \_d_d_d The escape \_d_d_d 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 construc- tion is _\_0 (not followed by a digit), which indicates the character _N_U_L. 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 int. _2._4._4. _F_l_o_a_t_i_n_g _C_o_n_s_t_a_n_t_s A floating constant consists of an integer part, a decimal point, a fraction part, an _e or E, and an optionally signed integer exponent. The integer and fraction parts both consist of a sequence of digits. Either the integer September 2, 1987 - 4 - part or the fraction part (not both) may be missing. Either the decimal point or the _e and the exponent (not both) may be missing. Every floating constant has type double. _2._4._5. _E_n_u_m_e_r_a_t_i_o_n _C_o_n_s_t_a_n_t_s Names declared as enumerators (see ``Structure, Union, and Enumeration Declarations'' under ``DECLARATIONS'') have type int. _2._5. _S_t_r_i_n_g_s A string is a sequence of characters surrounded by dou- ble quotes, as in "...". A string has type ``array of char'' and storage class static (see ``NAMES'') and is ini- tialized with the given characters. The compiler places a null byte (\0) at the end of each string so that programs which scan the string can find its end. In a string, the double quote character (") must be preceded by a \; in addi- tion, the same escapes as described for character constants may be used. A _\ and the immediately following new-line are ignored. All strings, even when written identically, are distinct. _2._6. _H_a_r_d_w_a_r_e _C_h_a_r_a_c_t_e_r_i_s_t_i_c_s The following figure summarize certain hardware proper- ties that vary from machine to machine. 8 _______________________________________________________ DEC PDP-11 DEC VAX-11 AT&T 3B (ASCII) (ASCII) (ASCII) 8 _______________________________________________________ char 8 bits 8 bits 8bits int 16 32 32 short 16 16 16 long 32 32 32 float 32 32 32 double 64 64 64 +_38 +_38 +_38 8 float range +_10 +_10 +_10 8 +_38 +_38 +_308 8 double range +_10 +_10 +_10 8 8 _______________________________________________________ 7 |7|7|7|7|7|7|7|7|7|7|7|7|7| |8|7|7|7|7|7|7|7|7|7| 9 |8|7|7|7|7|7|7|7|7|7| 9 |8|7|7|7|7|7|7|7|7|7| 9 |7|7|7|7|7|7|7|7|7|7|7|7|7| _3. _S_y_n_t_a_x _N_o_t_a_t_i_o_n Syntactic categories are indicated by _i_t_a_l_i_c type and literal words and characters in bold type. Alternative categories are listed on separate lines. An optional 9 September 2, 1987 - 5 - terminal or nonterminal symbol is indicated by the subscript ``opt,'' so that { _e_x_p_r_e_s_s_i_o_n9_o_p_t8 } indicates an optional expression enclosed in braces. The syntax is summarized in ``SYNTAX SUMMARY''. _4. _N_a_m_e_s The C language bases the interpretation of an identif- ier upon two attributes of the identifier - its _s_t_o_r_a_g_e _c_l_a_s_s and its _t_y_p_e. The storage class determines the loca- tion and lifetime of the storage associated with an identif- ier; the type determines the meaning of the values found in the identifier's storage. _4._1. _S_t_o_r_a_g_e _C_l_a_s_s There are four declarable storage classes: Automatic Static External Register. Automatic variables are local to each invocation of a block (see ``Compound Statement or Block'' in ``STATE- MENTS'') 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 com- munication between functions, even separately compiled func- tions. 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. _4._2. _T_y_p_e The C language supports several fundamental types of objects. Objects declared as characters (char) are large enough to store any member of the implementation's character set. If a genuine character from that character set is stored in a char variable, its value is equivalent to the integer code for that character. Other quantities may be stored into character variables, but the implementation is machine dependent. In particular, char may be signed or unsigned by default. Up to three sizes of integer, declared _s_h_o_r_t int, int, and _l_o_n_g int, are available. Longer integers provide no less storage than shorter ones, but the implementation may make either short integers or long integers, or both, equivalent to plain integers. ``Plain'' integers have the natural size suggested by the host machine architecture. September 2, 1987 - 6 - The other sizes are provided to meet special needs. The properties of enum types (see ``Structure, Union, and Enumeration Declarations'' under ``DECLARATIONS'') are identical to those of some integer types. The implementa- tion may use the range of values to determine how to allo- cate storage. Unsigned integers, declared _u_n_s_i_g_n_e_d, obey the laws of arithmetic modulo 28_n9 where _n is the number of bits in the representation. (On the PDP-11, unsigned long quantities are not supported.) Single-precision floating point (float) and double pre- cision floating point (double) may be synonymous in some implementations. Because objects of the foregoing types can usefully be interpreted as numbers, they will be referred to as _a_r_i_t_h_- _m_e_t_i_c types. Char, _i_n_t of all sizes whether unsigned or not, and _e_n_u_m will collectively be called _i_n_t_e_g_r_a_l types. The _f_l_o_a_t and _d_o_u_b_l_e types will collectively be called _f_l_o_a_t_i_n_g types. The _v_o_i_d type specifies an empty set of values. It is used as the type returned by functions that generate no value. Besides the fundamental arithmetic types, there is a conceptually infinite class of derived types constructed from the fundamental types in the following ways: _A_r_r_a_y_s of objects of most types _F_u_n_c_t_i_o_n_s which return objects of a given type _P_o_i_n_t_e_r_s to objects of a given type _S_t_r_u_c_t_u_r_e_s containing a sequence of objects of various types _U_n_i_o_n_s capable of containing any one of several objects of various types. In general these methods of constructing objects can be applied recursively. _5. _O_b_j_e_c_t_s _a_n_d _L_v_a_l_u_e_s An _o_b_j_e_c_t is a manipulatable region of storage. An _l_v_a_l_u_e 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 _E is an expression of pointer type, then *_E is an lvalue expression referring to the object to which _E points. The name ``lvalue'' comes from the assignment expression _E_1 = _E_2 in which the left operand _E_1 must be an lvalue expression. The discussion of each operator below indicates whether it expects lvalue operands and whether it yields an lvalue. September 2, 1987 - 7 - _6. _C_o_n_v_e_r_s_i_o_n_s A number of operators may, depending on their operands, cause conversion of the value of an operand from one type to another. This part explains the result to be expected from such conversions. The conversions demanded by most ordinary operators are summarized under ``Arithmetic Conversions.'' The summary will be supplemented as required by the discus- sion of each operator. _6._1. _C_h_a_r_a_c_t_e_r_s _a_n_d _I_n_t_e_g_e_r_s 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, _c_h_a_r variables range in value from -128 to 127. The more explicit type _u_n_s_i_g_n_e_d _c_h_a_r forces the values to range from 0 to 255. On machines that treat characters as signed, the char- acters 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, '\377' has the value -_1. When a longer integer is converted to a shorter integer or to a _c_h_a_r, it is truncated on the left. Excess bits are simply discarded. _6._2. _F_l_o_a_t _a_n_d _D_o_u_b_l_e All floating arithmetic in C is carried out in double precision. Whenever a _f_l_o_a_t appears in an expression it is lengthened to _d_o_u_b_l_e by zero padding its fraction. When a _d_o_u_b_l_e must be converted to float, for example by an assign- ment, the _d_o_u_b_l_e is rounded before truncation to _f_l_o_a_t 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. _6._3. _F_l_o_a_t_i_n_g _a_n_d _I_n_t_e_g_r_a_l Conversions of floating values to integral type are rather machine dependent. In particular, the direction of truncation of negative numbers varies. The result is unde- fined if it will not fit in the space provided. Conversions of integral values to floating type are well behaved. Some loss of accuracy occurs if the September 2, 1987 - 8 - destination lacks sufficient bits. _6._4. _P_o_i_n_t_e_r_s _a_n_d _I_n_t_e_g_e_r_s An expression of integral type may be added to or sub- tracted from a pointer; in such a case, the first is con- verted as specified in the discussion of the addition opera- tor. Two pointers to objects of the same type may be sub- tracted; in this case, the result is converted to an integer as specified in the discussion of the subtraction operator. _6._5. _U_n_s_i_g_n_e_d 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 28wordsize9). In a 2's complement representation, this conversion is concep- tual; and there is no actual change in the bit pattern. When an unsigned short integer is converted to long, the value of the result is the same numerically as that of the unsigned integer. Thus the conversion amounts to pad- ding with zeros on the left. _6._6. _A_r_i_t_h_m_e_t_i_c _C_o_n_v_e_r_s_i_o_n_s A great many operators cause conversions and yield result types in a similar way. This pattern will be called the ``usual arithmetic conversions.'' First, any operands of type _c_h_a_r or _s_h_o_r_t are converted to int, and any operands of type unsigned char or unsigned short are converted to unsigned int. Then, if either operand is _d_o_u_b_l_e, the other is converted to _d_o_u_b_l_e and that is the type of the result. Otherwise, if either operand is unsigned long, the other is converted to unsigned long and that is the type of the result. Otherwise, if either operand is long, the other is converted to _l_o_n_g and that is the type of the result. Oth- erwise, if one operand is long, and the other is unsigned int, they are both converted to unsigned long and that is the type of the result. Otherwise, if either operand is _u_n_s_i_g_n_e_d, the other is converted to _u_n_s_i_g_n_e_d and that is the type of the result. Otherwise, both operands must be int, and that is the type of the result. _6._7. _V_o_i_d The (nonexistent) value of a _v_o_i_d object may not be used in any way, and neither explicit nor implicit conver- sion may be applied. Because a void expression denotes a nonexistent value, such an expression may be used only as an expression statement (see ``Expression Statement'' under ``STATEMENTS'') or as the left operand of a comma expression (see ``Comma Operator'' under ``EXPRESSIONS''). September 2, 1987 - 9 - An expression may be converted to type _v_o_i_d by use of a cast. For example, this makes explicit the discarding of the value of a function call used as an expression state- ment. _7. _E_x_p_r_e_s_s_i_o_n_s 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 + (see ``Additive Opera- tors'') are those expressions defined under ``Primary Expressions'', ``Unary Operators'', and ``Multiplicative Operators''. Within each subpart, the operators have the same precedence. Left- or right-associativity is specified in each subsection for the operators discussed therein. The precedence and associativity of all the expression operators are summarized in the grammar of ``SYNTAX SUMMARY''. 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 asso- ciative operator (*, +, &, |, ^) may be rearranged arbi- trarily even in the presence of parentheses; to force a par- ticular order of evaluation, an explicit temporary must be used. 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. _7._1. _P_r_i_m_a_r_y _E_x_p_r_e_s_s_i_o_n_s Primary expressions involving ., ->, subscripting, and function calls group left to right. _p_r_i_m_a_r_y-_e_x_p_r_e_s_s_i_o_n: _i_d_e_n_t_i_f_i_e_r _c_o_n_s_t_a_n_t _s_t_r_i_n_g ( _e_x_p_r_e_s_s_i_o_n ) _p_r_i_m_a_r_y-_e_x_p_r_e_s_s_i_o_n [ _e_x_p_r_e_s_s_i_o_n ] _p_r_i_m_a_r_y-_e_x_p_r_e_s_s_i_o_n ( _e_x_p_r_e_s_s_i_o_n-_l_i_s_t9_o_p_t8 ) _p_r_i_m_a_r_y-_e_x_p_r_e_s_s_i_o_n . _i_d_e_n_t_i_f_i_e_r _p_r_i_m_a_r_y-_e_x_p_r_e_s_s_i_o_n -> _i_d_e_n_t_i_f_i_e_r September 2, 1987 - 10 - _e_x_p_r_e_s_s_i_o_n-_l_i_s_t: _e_x_p_r_e_s_s_i_o_n _e_x_p_r_e_s_s_i_o_n-_l_i_s_t , _e_x_p_r_e_s_s_i_o_n An identifier is a primary expression provided it has been suitably declared as discussed below. Its type is specified by its declaration. If the type of the identifier is ``array of ...'', then the value of the identifier expression is a pointer to the first object in the array; and the type of the expression is ``pointer to ...''. More- over, an array identifier is not an lvalue expression. Likewise, an identifier which is declared ``function return- ing ...'', when used except in the function-name position of a call, is converted to ``pointer to function returning ...''. A constant is a primary expression. Its type may be int, long, or _d_o_u_b_l_e depending on its form. Character con- stants have type _i_n_t and floating constants have type _d_o_u_- _b_l_e. A string is a primary expression. Its type is origi- nally ``array of char'', but following the same rule given above for identifiers, this is modified to ``pointer to char'' and the result is a pointer to the first character in the string. (There is an exception in certain initializers; see ``Initialization'' under ``DECLARATIONS.'') 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. A primary expression followed by an expression in square brackets is a primary expression. The intuitive meaning is that of a subscript. Usually, the primary expression has type ``pointer to ...'', the subscript expression is int, and the type of the result is ``...''. The expression _E_1[_E_2] is identical (by definition) to *((_E_1)+_E_2)). All the clues needed to understand this nota- tion are contained in this subpart together with the discus- sions in ``Unary Operators'' and ``Additive Operators'' on identifiers, * and + respectively. The implications are summarized under ``Arrays, Pointers, and Subscripting'' under ``TYPES REVISITED.'' A function call is a primary expression followed by parentheses containing a possibly empty, comma-separated list of expressions which constitute the actual arguments to the function. The primary expression must be of type ``function returning ...,'' and the result of the function call is of type ``...''. As indicated below, a hitherto September 2, 1987 - 11 - 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. Any actual arguments of type _f_l_o_a_t are converted to _d_o_u_b_l_e before the call. Any of type _c_h_a_r or _s_h_o_r_t are con- verted to _i_n_t. Array names are converted to pointers. No other conversions are performed automatically; in particu- lar, the compiler does not compare the types of actual argu- ments with those of formal arguments. If conversion is needed, use a cast; see ``Unary Operators'' and ``Type Names'' under ``DECLARATIONS.'' 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 func- tion are permitted. 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. A primary expression followed by an arrow (built from - and > ) 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 _E_1->_M_O_S is the same as (*_E_1)._M_O_S. Structures and unions are discussed in ``Structure, Union, and Enumeration Declarations'' under ``DECLARATIONS.'' _7._2. _U_n_a_r_y _O_p_e_r_a_t_o_r_s Expressions with unary operators group right to left. September 2, 1987 - 12 - _u_n_a_r_y-_e_x_p_r_e_s_s_i_o_n: * _e_x_p_r_e_s_s_i_o_n & _l_v_a_l_u_e - _e_x_p_r_e_s_s_i_o_n ! _e_x_p_r_e_s_s_i_o_n ~ _e_x_p_r_e_s_s_i_o_n ++ _l_v_a_l_u_e --_l_v_a_l_u_e _l_v_a_l_u_e ++ _l_v_a_l_u_e -- ( _t_y_p_e-_n_a_m_e ) _e_x_p_r_e_s_s_i_o_n sizeof _e_x_p_r_e_s_s_i_o_n sizeof ( _t_y_p_e-_n_a_m_e ) The unary * operator means _i_n_d_i_r_e_c_t_i_o_n ; the expression must be a pointer, and the result is an lvalue referring to the object to which the expression points. If the type of the expression is ``pointer to ...,'' the type of the result is ``...''. The result of the unary & operator is a pointer to the object referred to by the lvalue. If the type of the lvalue is ``...'', the type of the result is ``pointer to ...''. The result of the unary - operator is the negative of its operand. The usual arithmetic conversions are per- formed. The negative of an unsigned quantity is computed by subtracting its value from 28_n9 where _n is the number of bits in the corresponding signed type. There is no unary + operator. The result of the logical negation operator ! 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 _i_n_t. It is applicable to any arithmetic type or to pointers. The ~ operator yields the one's complement of its operand. The usual arithmetic conversions are performed. The type of the operand must be integral. The object referred to by the lvalue operand of prefix ++ is incremented. The value is the new value of the operand but is not an lvalue. The expression ++_x is equivalent to x=x+1. See the discussions ``Additive Opera- tors'' and ``Assignment Operators'' for information on conversions. The lvalue operand of prefix -- is decremented analo- gously to the prefix ++ operator. When postfix ++ is applied to an lvalue, the result is September 2, 1987 - 13 - 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 ++ operator. The type of the result is the same as the type of the lvalue expression. When postfix -- 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 -- operator. The type of the result is the same as the type of the lvalue expression. 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 _c_a_s_t. Type names are described in ``Type Names'' under ``Declara- tions.'' The _s_i_z_e_o_f operator yields the size in bytes of its operand. (A _b_y_t_e is undefined by the language except in terms of the value of _s_i_z_e_o_f. However, in all existing implementations, a byte is the space required to hold a char.) 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 _u_n_s_i_g_n_e_d 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. The _s_i_z_e_o_f 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. The construction sizeof(_t_y_p_e) is taken to be a unit, so the expression sizeof(_t_y_p_e)-2 is the same as (sizeof(_t_y_p_e))-2. _7._3. _M_u_l_t_i_p_l_i_c_a_t_i_v_e _O_p_e_r_a_t_o_r_s The multiplicative operators *, /, and % group left to right. The usual arithmetic conversions are performed. _m_u_l_t_i_p_l_i_c_a_t_i_v_e _e_x_p_r_e_s_s_i_o_n: _e_x_p_r_e_s_s_i_o_n * _e_x_p_r_e_s_s_i_o_n _e_x_p_r_e_s_s_i_o_n / _e_x_p_r_e_s_s_i_o_n _e_x_p_r_e_s_s_i_o_n % _e_x_p_r_e_s_s_i_o_n The binary * operator indicates multiplication. The * operator is associative, and expressions with several multi- plications at the same level may be rearranged by the com- piler. The binary / operator indicates division. The binary % operator yields the remainder from the September 2, 1987 - 14 - division of the first expression by the second. The operands must be integral. 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 (_a/_b)*_b + _a%_b is equal to _a (if _b is not 0). _7._4. _A_d_d_i_t_i_v_e _O_p_e_r_a_t_o_r_s The additive operators + and - group left to right. The usual arithmetic conversions are performed. There are some additional type possibilities for each operator. _a_d_d_i_t_i_v_e-_e_x_p_r_e_s_s_i_o_n: _e_x_p_r_e_s_s_i_o_n + _e_x_p_r_e_s_s_i_o_n _e_x_p_r_e_s_s_i_o_n - _e_x_p_r_e_s_s_i_o_n The result of the + 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, appropri- ately offset from the original object. Thus if _P is a pointer to an object in an array, the expression _P+_1 is a pointer to the next object in the array. No further type combinations are allowed for pointers. The + operator is associative, and expressions with several additions at the same level may be rearranged by the compiler. The result of the - 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. If two pointers to objects of the same type are sub- tracted, the result is converted (by division by the length of the object) to an _i_n_t 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. September 2, 1987 - 15 - _7._5. _S_h_i_f_t _O_p_e_r_a_t_o_r_s The shift operators << and >> 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 int; 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. _s_h_i_f_t-_e_x_p_r_e_s_s_i_o_n: _e_x_p_r_e_s_s_i_o_n << _e_x_p_r_e_s_s_i_o_n _e_x_p_r_e_s_s_i_o_n >> _e_x_p_r_e_s_s_i_o_n The value of _E_1<<_E_2 is _E_1 (interpreted as a bit pat- tern) left-shifted _E_2 bits. Vacated bits are 0 filled. The value of _E_1>>_E_2 is _E_1 right-shifted _E_2 bit positions. The right shift is guaranteed to be logical (0 fill) if _E_1 is unsigned; otherwise, it may be arithmetic. _7._6. _R_e_l_a_t_i_o_n_a_l _O_p_e_r_a_t_o_r_s The relational operators group left to right. _r_e_l_a_t_i_o_n_a_l-_e_x_p_r_e_s_s_i_o_n: _e_x_p_r_e_s_s_i_o_n < _e_x_p_r_e_s_s_i_o_n _e_x_p_r_e_s_s_i_o_n > _e_x_p_r_e_s_s_i_o_n _e_x_p_r_e_s_s_i_o_n <= _e_x_p_r_e_s_s_i_o_n _e_x_p_r_e_s_s_i_o_n >= _e_x_p_r_e_s_s_i_o_n The operators < (less than), > (greater than), <= (less than or equal to), and >= (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 _i_n_t. 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. _7._7. _E_q_u_a_l_i_t_y _O_p_e_r_a_t_o_r_s _e_q_u_a_l_i_t_y-_e_x_p_r_e_s_s_i_o_n: _e_x_p_r_e_s_s_i_o_n == _e_x_p_r_e_s_s_i_o_n _e_x_p_r_e_s_s_i_o_n != _e_x_p_r_e_s_s_i_o_n The == (equal to) and the != (not equal to) operators are exactly analogous to the relational operators except for their lower precedence. (Thus _a<_b == _c<_d is 1 whenever _a<_b September 2, 1987 - 16 - and _c<_d have the same truth value). 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. _7._8. _B_i_t_w_i_s_e _A_N_D _O_p_e_r_a_t_o_r _a_n_d-_e_x_p_r_e_s_s_i_o_n: _e_x_p_r_e_s_s_i_o_n & _e_x_p_r_e_s_s_i_o_n The & operator is associative, and expressions involv- ing & 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. _7._9. _B_i_t_w_i_s_e _E_x_c_l_u_s_i_v_e _O_R _O_p_e_r_a_t_o_r _e_x_c_l_u_s_i_v_e-_o_r-_e_x_p_r_e_s_s_i_o_n: _e_x_p_r_e_s_s_i_o_n ^ _e_x_p_r_e_s_s_i_o_n The ^ operator is associative, and expressions involv- ing ^ may be rearranged. The usual arithmetic conversions are performed; the result is the bitwise exclusive OR func- tion of the operands. The operator applies only to integral operands. _7._1_0. _B_i_t_w_i_s_e _I_n_c_l_u_s_i_v_e _O_R _O_p_e_r_a_t_o_r _i_n_c_l_u_s_i_v_e-_o_r-_e_x_p_r_e_s_s_i_o_n: _e_x_p_r_e_s_s_i_o_n | _e_x_p_r_e_s_s_i_o_n The | operator is associative, and expressions involv- ing | may be rearranged. The usual arithmetic conversions are performed; the result is the bitwise inclusive OR func- tion of its operands. The operator applies only to integral operands. _7._1_1. _L_o_g_i_c_a_l _A_N_D _O_p_e_r_a_t_o_r _l_o_g_i_c_a_l-_a_n_d-_e_x_p_r_e_s_s_i_o_n: _e_x_p_r_e_s_s_i_o_n && _e_x_p_r_e_s_s_i_o_n The && operator groups left to right. It returns 1 if both its operands evaluate to nonzero, 0 otherwise. Unlike &, && guarantees left to right evaluation; moreover, the September 2, 1987 - 17 - second operand is not evaluated if the first operand is 0. 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 _i_n_t. _7._1_2. _L_o_g_i_c_a_l _O_R _O_p_e_r_a_t_o_r _l_o_g_i_c_a_l-_o_r-_e_x_p_r_e_s_s_i_o_n: _e_x_p_r_e_s_s_i_o_n || _e_x_p_r_e_s_s_i_o_n The || operator groups left to right. It returns 1 if either of its operands evaluates to nonzero, 0 otherwise. Unlike |, || guarantees left to right evaluation; moreover, the second operand is not evaluated if the value of the first operand is nonzero. 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 _i_n_t. _7._1_3. _C_o_n_d_i_t_i_o_n_a_l _O_p_e_r_a_t_o_r _c_o_n_d_i_t_i_o_n_a_l-_e_x_p_r_e_s_s_i_o_n: _e_x_p_r_e_s_s_i_o_n ? _e_x_p_r_e_s_s_i_o_n : _e_x_p_r_e_s_s_i_o_n 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 com- mon 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. _7._1_4. _A_s_s_i_g_n_m_e_n_t _O_p_e_r_a_t_o_r_s 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. September 2, 1987 - 18 - _a_s_s_i_g_n_m_e_n_t-_e_x_p_r_e_s_s_i_o_n: _l_v_a_l_u_e = _e_x_p_r_e_s_s_i_o_n _l_v_a_l_u_e += _e_x_p_r_e_s_s_i_o_n _l_v_a_l_u_e -= _e_x_p_r_e_s_s_i_o_n _l_v_a_l_u_e *= _e_x_p_r_e_s_s_i_o_n _l_v_a_l_u_e /= _e_x_p_r_e_s_s_i_o_n _l_v_a_l_u_e %= _e_x_p_r_e_s_s_i_o_n _l_v_a_l_u_e >>= _e_x_p_r_e_s_s_i_o_n _l_v_a_l_u_e <<= _e_x_p_r_e_s_s_i_o_n _l_v_a_l_u_e &= _e_x_p_r_e_s_s_i_o_n _l_v_a_l_u_e ^= _e_x_p_r_e_s_s_i_o_n _l_v_a_l_u_e |= _e_x_p_r_e_s_s_i_o_n In the simple assignment with =, 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. The behavior of an expression of the form E1 _o_p = E2 may be inferred by taking it as equivalent to E1 = E1 _o_p (E2); however, _E_1 is evaluated only once. In += and -=, the left operand may be a pointer; in which case, the (integral) right operand is converted as explained in ``Additive Opera- tors.'' All right operands and all nonpointer left operands must have arithmetic type. _7._1_5. _C_o_m_m_a _O_p_e_r_a_t_o_r _c_o_m_m_a-_e_x_p_r_e_s_s_i_o_n: _e_x_p_r_e_s_s_i_o_n , _e_x_p_r_e_s_s_i_o_n A pair of expressions separated by a comma is evaluated left to right, and the value of the left expression is dis- carded. 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 ``Pri- mary Expressions'') and lists of initializers (see ``Ini- tialization'' under ``DECLARATIONS''), the comma operator as described in this subpart can only appear in parentheses. For example, f(a, (t=3, t+2), c) September 2, 1987 - 19 - has three arguments, the second of which has the value 5. _8. _D_e_c_l_a_r_a_t_i_o_n_s Declarations are used to specify the interpretation which C gives to each identifier; they do not necessarily reserve storage associated with the identifier. Declara- tions have the form _d_e_c_l_a_r_a_t_i_o_n: _d_e_c_l-_s_p_e_c_i_f_i_e_r_s _d_e_c_l_a_r_a_t_o_r-_l_i_s_t9_o_p_t8 ; The declarators in the declarator-list contain the identifiers being declared. The decl-specifiers consist of a sequence of type and storage class specifiers. _d_e_c_l-_s_p_e_c_i_f_i_e_r_s: _t_y_p_e-_s_p_e_c_i_f_i_e_r _d_e_c_l-_s_p_e_c_i_f_i_e_r_s9_o_p_t 8 _s_c-_s_p_e_c_i_f_i_e_r _d_e_c_l-_s_p_e_c_i_f_i_e_r_s9_o_p_t 9 The list must be self-consistent in a way described below. _8._1. _S_t_o_r_a_g_e _C_l_a_s_s _S_p_e_c_i_f_i_e_r_s The sc-specifiers are: _s_c-_s_p_e_c_i_f_i_e_r: auto static extern register typedef The _t_y_p_e_d_e_f specifier does not reserve storage and is called a ``storage class specifier'' only for syntactic con- venience. See ``Typedef'' for more information. The mean- ings of the various storage classes were discussed in ``Names.'' The auto, static, and _r_e_g_i_s_t_e_r declarations also serve as definitions in that they cause an appropriate amount of storage to be reserved. In the _e_x_t_e_r_n case, there must be an external definition (see ``External Definitions'') for the given identifiers somewhere outside the function in which they are declared. A _r_e_g_i_s_t_e_r declaration is best thought of as an _a_u_t_o 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, September 2, 1987 - 20 - only variables of certain types will be stored in registers; on the PDP-11, they are _i_n_t or pointer. One other restric- tion applies to register variables: the address-of operator & 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. At most, one sc-specifier may be given in a declara- tion. If the sc-specifier is missing from a declaration, it is taken to be _a_u_t_o inside a function, _e_x_t_e_r_n outside. Exception: functions are never automatic. _8._2. _T_y_p_e _S_p_e_c_i_f_i_e_r_s The type-specifiers are _t_y_p_e-_s_p_e_c_i_f_i_e_r: _s_t_r_u_c_t-_o_r-_u_n_i_o_n-_s_p_e_c_i_f_i_e_r _t_y_p_e_d_e_f-_n_a_m_e _e_n_u_m-_s_p_e_c_i_f_i_e_r _b_a_s_i_c-_t_y_p_e-_s_p_e_c_i_f_i_e_r: _b_a_s_i_c-_t_y_p_e _b_a_s_i_c-_t_y_p_e _b_a_s_i_c-_t_y_p_e-_s_p_e_c_i_f_i_e_r_s _b_a_s_i_c-_t_y_p_e: char short int long unsigned float double void At most one of the words long or short may be specified in conjunction with int; the meaning is the same as if int were not mentioned. The word long may be specified in con- junction with float; the meaning is the same as double. The word unsigned may be specified alone, or in conjunction with int or any of its short or long varieties, or with char. Otherwise, at most on type-specifier may be given in a declaration. In particular, adjectival use of long, short, or unsigned is not permitted with typedef names. If the type-specifier is missing from a declaration, it is taken to be int. Specifiers for structures, unions, and enumerations are discussed in ``Structure, Union, and Enumeration Declara- tions.'' Declarations with _t_y_p_e_d_e_f names are discussed in ``Typedef.'' September 2, 1987 - 21 - _8._3. _D_e_c_l_a_r_a_t_o_r_s The declarator-list appearing in a declaration is a comma-separated sequence of declarators, each of which may have an initializer. _d_e_c_l_a_r_a_t_o_r-_l_i_s_t: _i_n_i_t-_d_e_c_l_a_r_a_t_o_r _i_n_i_t-_d_e_c_l_a_r_a_t_o_r , _d_e_c_l_a_r_a_t_o_r-_l_i_s_t _i_n_i_t-_d_e_c_l_a_r_a_t_o_r: _d_e_c_l_a_r_a_t_o_r _i_n_i_t_i_a_l_i_z_e_r9_o_p_t 9 Initializers are discussed in ``Initialization''. The specifiers in the declaration indicate the type and storage class of the objects to which the declarators refer. Declarators have the syntax: _d_e_c_l_a_r_a_t_o_r: _i_d_e_n_t_i_f_i_e_r ( _d_e_c_l_a_r_a_t_o_r ) * _d_e_c_l_a_r_a_t_o_r _d_e_c_l_a_r_a_t_o_r () _d_e_c_l_a_r_a_t_o_r [ _c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n9_o_p_t8 ] The grouping is the same as in expressions. _8._4. _M_e_a_n_i_n_g _o_f _D_e_c_l_a_r_a_t_o_r_s 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. Each declarator contains exactly one identifier; it is this identifier that is declared. If an unadorned identif- ier appears as a declarator, then it has the type indicated by the specifier heading the declaration. A declarator in parentheses is identical to the una- dorned declarator, but the binding of complex declarators may be altered by parentheses. See the examples below. Now imagine a declaration T D1 where _T is a type-specifier (like int, etc.) and _D_1 is a declarator. Suppose this declaration makes the identifier have type ``... _T ,'' where the ``...'' is empty if _D_1 is September 2, 1987 - 22 - just a plain identifier (so that the type of _x in `int x'' is just int). Then if _D_1 has the form *D the type of the contained identifier is ``... pointer to _T .'' If _D_1 has the form D() then the contained identifier has the type ``... function returning T.'' If _D_1 has the form D[_c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n] or D[] then the contained identifier has type ``... array of T.'' In the first case, the constant expression is an expression whose value is determinable at compile time , whose type is _i_n_t, and whose value is positive. (Constant expressions are defined precisely in ``Constant Expressions.'') When several ``array of'' specifications are adjacent, a multidimensional array is created; the constant expressions which specify the bounds of the arrays may be missing only for the first member of the sequence. This elision is useful when the array is external and the actual definition, which allocates storage, is given elsewhere. The first constant expression may also be omitted when the declarator is followed by ini- tialization. In this case the size is calculated from the number of initial elements supplied. 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). 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. September 2, 1987 - 23 - As an example, the declaration int i, *ip, f(), *fip(), (*pfi)(); declares an integer i, a pointer _i_p to an integer, a func- tion _f returning an integer, a function _f_i_p returning a pointer to an integer, and a pointer _p_f_i to a function which returns an integer. It is especially useful to compare the last two. The binding of *_f_i_p() is *(_f_i_p()). The declara- tion suggests, and the same construction in an expression requires, the calling of a function _f_i_p. Using indirection through the (pointer) result to yield an integer. In the declarator (*pfi)(), 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. As another example, float fa[17], *afp[17]; declares an array of _f_l_o_a_t numbers and an array of pointers to _f_l_o_a_t numbers. Finally, static int x3d[3][5][7]; declares a static 3-dimensional array of integers, with rank 3x5x7. In complete detail, _x_3_d 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 expres- sions x3d, x3d[i], x3d[i][j], _x_3_d[_i][_j][_k] may reasonably appear in an expression. The first three have type ``array'' and the last has type _i_n_t. _8._5. _S_t_r_u_c_t_u_r_e _a_n_d _U_n_i_o_n _D_e_c_l_a_r_a_t_i_o_n_s 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. _s_t_r_u_c_t-_o_r-_u_n_i_o_n-_s_p_e_c_i_f_i_e_r: _s_t_r_u_c_t-_o_r-_u_n_i_o_n { _s_t_r_u_c_t-_d_e_c_l-_l_i_s_t } _s_t_r_u_c_t-_o_r-_u_n_i_o_n _i_d_e_n_t_i_f_i_e_r { _s_t_r_u_c_t-_d_e_c_l-_l_i_s_t } _s_t_r_u_c_t-_o_r-_u_n_i_o_n _i_d_e_n_t_i_f_i_e_r _s_t_r_u_c_t-_o_r-_u_n_i_o_n: struct union September 2, 1987 - 24 - The struct-decl-list is a sequence of declarations for the members of the structure or union: _s_t_r_u_c_t-_d_e_c_l-_l_i_s_t: _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_i_o_n _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_i_o_n _s_t_r_u_c_t-_d_e_c_l-_l_i_s_t _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_i_o_n: _t_y_p_e-_s_p_e_c_i_f_i_e_r _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_o_r-_l_i_s_t ; _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_o_r-_l_i_s_t: _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_o_r _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_o_r , _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_o_r-_l_i_s_t In the usual case, a struct-declarator is just a declarator for a member of a structure or union. A struc- ture member may also consist of a specified number of bits. Such a member is also called a _f_i_e_l_d ; its length, a non- negative constant expression, is set off from the field name by a colon. _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_o_r: _d_e_c_l_a_r_a_t_o_r _d_e_c_l_a_r_a_t_o_r : _c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n : _c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n 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. Fields are assigned right to left on the PDP-11 and VAX-11, left to right on the 3B 20. 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. 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 _i_n_t 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 _i_n_t are treated as containing a September 2, 1987 - 25 - sign. For these reasons, it is strongly recommended that fields be declared as _u_n_s_i_g_n_e_d. In all implementations, there are no arrays of fields, and the address-of operator & may not be applied to them, so that there are no pointers to fields. 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. A structure or union specifier of the second form, that is, one of struct _i_d_e_n_t_i_f_i_e_r { _s_t_r_u_c_t-_d_e_c_l-_l_i_s_t } union _i_d_e_n_t_i_f_i_e_r { _s_t_r_u_c_t-_d_e_c_l-_l_i_s_t } declares the identifier to be the _s_t_r_u_c_t_u_r_e _t_a_g (or union tag) of the structure specified by the list. A subsequent declaration may then use the third form of specifier, one of struct _i_d_e_n_t_i_f_i_e_r union _i_d_e_n_t_i_f_i_e_r 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. The third form of a structure or union specifier may be used prior to a declaration which gives the complete specif- ication 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 typedef 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. 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. A simple but important example of a structure declara- tion is the following binary tree structure: September 2, 1987 - 26 - struct tnode { char tword[20]; int count; struct tnode *left; struct tnode *right; }; which contains an array of 20 characters, an integer, and two pointers to similar structures. Once this declaration has been given, the declaration struct tnode s, *sp; declares _s to be a structure of the given sort and _s_p to be a pointer to a structure of the given sort. With these declarations, the expression sp->count refers to the _c_o_u_n_t field of the structure to which _s_p points; s.left refers to the left subtree pointer of the structure s; and s.right->tword[0] refers to the first character of the _t_w_o_r_d member of the right subtree of _s. _8._6. _E_n_u_m_e_r_a_t_i_o_n _D_e_c_l_a_r_a_t_i_o_n_s Enumeration variables and constants have integral type. September 2, 1987 - 27 - _e_n_u_m-_s_p_e_c_i_f_i_e_r: enum { _e_n_u_m-_l_i_s_t } enum _i_d_e_n_t_i_f_i_e_r { _e_n_u_m-_l_i_s_t } enum _i_d_e_n_t_i_f_i_e_r _e_n_u_m-_l_i_s_t: _e_n_u_m_e_r_a_t_o_r _e_n_u_m-_l_i_s_t , _e_n_u_m_e_r_a_t_o_r _e_n_u_m_e_r_a_t_o_r: _i_d_e_n_t_i_f_i_e_r _i_d_e_n_t_i_f_i_e_r = _c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n The identifiers in an enum-list are declared as con- stants and may appear wherever constants are required. If no enumerators with = appear, then the values of the corresponding constants begin at 0 and increase by 1 as the declaration is read from left to right. An enumerator with = gives the associated identifier the value indicated; sub- sequent identifiers continue the progression from the assigned value. The names of enumerators in the same scope must all be distinct from each other and from those of ordinary vari- ables. The role of the identifier in the enum-specifier is entirely analogous to that of the structure tag in a struct-specifier; it names a particular enumeration. For example, enum color { chartreuse, burgundy, claret=20, winedark }; ... enum color **cp, col; ... col = claret; cp = &col; ... if (**cp == burgundy) ... makes _c_o_l_o_r the enumeration-tag of a type describing various colors, and then declares _c_p as a pointer to an object of that type, and _c_o_l as an object of that type. The possible values are drawn from the set {0,1,20,21}. _8._7. _I_n_i_t_i_a_l_i_z_a_t_i_o_n A declarator may specify an initial value for the iden- tifier being declared. The initializer is preceded by = and consists of an expression or a list of values nested in braces. September 2, 1987 - 28 - _i_n_i_t_i_a_l_i_z_e_r: = _e_x_p_r_e_s_s_i_o_n = { _i_n_i_t_i_a_l_i_z_e_r-_l_i_s_t } = { _i_n_i_t_i_a_l_i_z_e_r-_l_i_s_t , } _i_n_i_t_i_a_l_i_z_e_r-_l_i_s_t: _e_x_p_r_e_s_s_i_o_n _i_n_i_t_i_a_l_i_z_e_r-_l_i_s_t , _i_n_i_t_i_a_l_i_z_e_r-_l_i_s_t { _i_n_i_t_i_a_l_i_z_e_r-_l_i_s_t } { _i_n_i_t_i_a_l_i_z_e_r-_l_i_s_t , } All the expressions in an initializer for a static or external variable must be constant expressions, which are described in ``CONSTANT EXPRESSIONS'', or expressions which reduce to the address of a previously declared variable, possibly offset by a constant expression. Automatic or register variables may be initialized by arbitrary expres- sions involving constants and previously declared variables and functions. 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. When an initializer applies to a _s_c_a_l_a_r (a pointer or an object of arithmetic type), it consists of a single expression, perhaps in braces. The initial value of the object is taken from the expression; the same conversions as for assignment are performed. When the declared variable is an _a_g_g_r_e_g_a_t_e (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. Braces may in some cases be omitted. If the initial- izer 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 initial- izers 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. September 2, 1987 - 29 - A final abbreviation allows a _c_h_a_r array to be initial- ized by a string. In this case successive characters of the string initialize the members of the array. For example, int x[] = { 1, 3, 5 }; declares and initializes _x as a one-dimensional array which has three members, since no size was specified and there are three initializers. float y[4][3] = { { 1, 3, 5 }, { 2, 4, 6 }, { 3, 5, 7 }, }; is a completely-bracketed initialization: 1, 3, and 5 ini- tialize the first row of the array y[0], namely y[0][0], y[0][1], and _y[_0][_2]. Likewise, the next two lines initial- ize _y[_1] and _y[_2]. The initializer ends early and therefore _y[_3] is initialized with 0. Precisely, the same effect could have been achieved by float y[4][3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7 }; The initializer for _y begins with a left brace but that for _y[_0] does not; therefore, three elements from the list are used. Likewise, the next three are taken successively for _y[_1] and _y[_2]. Also, float y[4][3] = { { 1 }, { 2 }, { 3 }, { 4 } }; initializes the first column of _y (regarded as a two- dimensional array) and leaves the rest 0. Finally, char msg[] = "Syntax error on line %s\n"; shows a character array whose members are initialized with a September 2, 1987 - 30 - string. _8._8. _T_y_p_e _N_a_m_e_s In two contexts (to specify type conversions explicitly by means of a cast and as an argument of sizeof), it is desired to supply the name of a data type. This is accom- plished using a ``type name'', which in essence is a declaration for an object of that type which omits the name of the object. _t_y_p_e-_n_a_m_e: _t_y_p_e-_s_p_e_c_i_f_i_e_r _a_b_s_t_r_a_c_t-_d_e_c_l_a_r_a_t_o_r _a_b_s_t_r_a_c_t-_d_e_c_l_a_r_a_t_o_r: _e_m_p_t_y ( _a_b_s_t_r_a_c_t-_d_e_c_l_a_r_a_t_o_r ) * _a_b_s_t_r_a_c_t-_d_e_c_l_a_r_a_t_o_r _a_b_s_t_r_a_c_t-_d_e_c_l_a_r_a_t_o_r () _a_b_s_t_r_a_c_t-_d_e_c_l_a_r_a_t_o_r [ _c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n9_o_p_t8 ] To avoid ambiguity, in the construction ( _a_b_s_t_r_a_c_t-_d_e_c_l_a_r_a_t_o_r ) 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, int int * int *[3] int (*)[3] int *() int (*)() int (*[3])() name respectively the types ``integer,'' ``pointer to integer,'' ``array of three pointers to integers,'' ``pointer to an array of three integers,'' ``function returning pointer to integer,'' ``pointer to function returning an integer,'' and ``array of three pointers to functions returning an integer.'' September 2, 1987 - 31 - _8._9. _T_y_p_e_d_e_f Declarations whose ``storage class'' is _t_y_p_e_d_e_f do not define storage but instead define identifiers which can be used later as if they were type keywords naming fundamental or derived types. _t_y_p_e_d_e_f-_n_a_m_e: _i_d_e_n_t_i_f_i_e_r Within the scope of a declaration involving typedef, each identifier appearing as part of any declarator therein becomes syntactically equivalent to the type keyword naming the type associated with the identifier in the way described in ``Meaning of Declarators.'' For example, after typedef int MILES, *KLICKSP; typedef struct { double re, im; } complex; the constructions MILES distance; extern KLICKSP metricp; complex z, *zp; are all legal declarations; the type of _d_i_s_t_a_n_c_e is int, that of _m_e_t_r_i_c_p is ``pointer to int, '' and that of _z is the specified structure. The _z_p is a pointer to such a struc- ture. The _t_y_p_e_d_e_f does not introduce brand-new types, only synonyms for types which could be specified in another way. Thus in the example above _d_i_s_t_a_n_c_e is considered to have exactly the same type as any other _i_n_t object. _9. _S_t_a_t_e_m_e_n_t_s Except as indicated, statements are executed in sequence. _9._1. _E_x_p_r_e_s_s_i_o_n _S_t_a_t_e_m_e_n_t Most statements are expression statements, which have the form _e_x_p_r_e_s_s_i_o_n ; Usually expression statements are assignments or func- tion calls. September 2, 1987 - 32 - _9._2. _C_o_m_p_o_u_n_d _S_t_a_t_e_m_e_n_t _o_r _B_l_o_c_k So that several statements can be used where one is expected, the compound statement (also, and equivalently, called ``block'') is provided: _c_o_m_p_o_u_n_d-_s_t_a_t_e_m_e_n_t: { _d_e_c_l_a_r_a_t_i_o_n-_l_i_s_t9_o_p_t8 _s_t_a_t_e_m_e_n_t-_l_i_s_t9_o_p_t8 } _d_e_c_l_a_r_a_t_i_o_n-_l_i_s_t: _d_e_c_l_a_r_a_t_i_o_n _d_e_c_l_a_r_a_t_i_o_n _d_e_c_l_a_r_a_t_i_o_n-_l_i_s_t _s_t_a_t_e_m_e_n_t-_l_i_s_t: _s_t_a_t_e_m_e_n_t _s_t_a_t_e_m_e_n_t _s_t_a_t_e_m_e_n_t-_l_i_s_t 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. Any initializations of _a_u_t_o or _r_e_g_i_s_t_e_r variables are performed each time the block is entered at the top. It is currently possible (but a bad practice) to transfer into a block; in that case the initializations are not performed. Initializations of _s_t_a_t_i_c variables are performed only once when the program begins execution. Inside a block, _e_x_t_e_r_n declarations do not reserve storage so initialization is not permitted. _9._3. _C_o_n_d_i_t_i_o_n_a_l _S_t_a_t_e_m_e_n_t The two forms of the conditional statement are if ( _e_x_p_r_e_s_s_i_o_n ) _s_t_a_t_e_m_e_n_t if ( _e_x_p_r_e_s_s_i_o_n ) _s_t_a_t_e_m_e_n_t else _s_t_a_t_e_m_e_n_t In both cases, the expression is evaluated; and if it is nonzero, the first substatement is executed. In the second case, the second substatement is executed if the expression is 0. The ``else'' ambiguity is resolved by con- necting an _e_l_s_e with the last encountered else-less _i_f. _9._4. _W_h_i_l_e _S_t_a_t_e_m_e_n_t The _w_h_i_l_e statement has the form while ( _e_x_p_r_e_s_s_i_o_n ) _s_t_a_t_e_m_e_n_t September 2, 1987 - 33 - 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. _9._5. _D_o _S_t_a_t_e_m_e_n_t The _d_o statement has the form do _s_t_a_t_e_m_e_n_t while ( _e_x_p_r_e_s_s_i_o_n ) ; The substatement is executed repeatedly until the value of the expression becomes 0. The test takes place after each execution of the statement. _9._6. _F_o_r _S_t_a_t_e_m_e_n_t The _f_o_r statement has the form: for ( _e_x_p-_19_o_p_t8 ; _e_x_p-_29_o_p_t8 ; _e_x_p-_39_o_p_t8 ) _s_t_a_t_e_m_e_n_t Except for the behavior of continue, this statement is equivalent to _e_x_p-_1 ; while ( _e_x_p-_2 ) { _s_t_a_t_e_m_e_n_t _e_x_p-_3 ; } 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 incre- menting that is performed after each iteration. Any or all of the expressions may be dropped. A miss- ing _e_x_p-_2 makes the implied _w_h_i_l_e clause equivalent to while(1); other missing expressions are simply dropped from the expansion above. _9._7. _S_w_i_t_c_h _S_t_a_t_e_m_e_n_t The _s_w_i_t_c_h statement causes control to be transferred to one of several statements depending on the value of an expression. It has the form switch ( _e_x_p_r_e_s_s_i_o_n ) _s_t_a_t_e_m_e_n_t September 2, 1987 - 34 - The usual arithmetic conversion is performed on the expression, but the result must be _i_n_t. The statement is typically compound. Any statement within the statement may be labeled with one or more case prefixes as follows: case _c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n : where the constant expression must be _i_n_t. No two of the case constants in the same switch may have the same value. Constant expressions are precisely defined in ``CONSTANT EXPRESSIONS.'' There may also be at most one statement prefix of the form default : When the _s_w_i_t_c_h 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 expres- sion, control is passed to the statement following the matched case prefix. If no case constant matches the expression and if there is a default, prefix, control passes to the prefixed statement. If no case matches and if there is no default, then none of the statements in the switch is executed. The prefixes _c_a_s_e and _d_e_f_a_u_l_t do not alter the flow of control, which continues unimpeded across such prefixes. To exit from a switch, see ``Break Statement.'' 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. _9._8. _B_r_e_a_k _S_t_a_t_e_m_e_n_t The statement break ; causes termination of the smallest enclosing while, do, for, or switch statement; control passes to the statement follow- ing the terminated statement. _9._9. _C_o_n_t_i_n_u_e _S_t_a_t_e_m_e_n_t The statement continue ; September 2, 1987 - 35 - causes control to pass to the loop-continuation portion of the smallest enclosing while, do, or for statement; that is to the end of the loop. More precisely, in each of the statements while (...) { do { for (...) { _s_t_a_t_e_m_e_n_t ; _s_t_a_t_e_m_e_n_t ; _s_t_a_t_e_m_e_n_t ; contin: ; contin: ; contin: ; } } while (...); } a _c_o_n_t_i_n_u_e is equivalent to _g_o_t_o _c_o_n_t_i_n. (Following the _c_o_n_t_i_n: is a null statement, see ``Null Statement''.) _9._1_0. _R_e_t_u_r_n _S_t_a_t_e_m_e_n_t A function returns to its caller by means of the _r_e_t_u_r_n statement which has one of the forms return ; return _e_x_p_r_e_s_s_i_o_n ; 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 expres- sion may be parenthesized. _9._1_1. _G_o_t_o _S_t_a_t_e_m_e_n_t Control may be transferred unconditionally by means of the statement goto _i_d_e_n_t_i_f_i_e_r ; The identifier must be a label (see ``Labeled State- ment'') located in the current function. _9._1_2. _L_a_b_e_l_e_d _S_t_a_t_e_m_e_n_t Any statement may be preceded by label prefixes of the form _i_d_e_n_t_i_f_i_e_r : which serve to declare the identifier as a label. The only use of a label is as a target of a _g_o_t_o. The scope of a September 2, 1987 - 36 - label is the current function, excluding any subblocks in which the same identifier has been redeclared. See ``SCOPE RULES.'' _9._1_3. _N_u_l_l _S_t_a_t_e_m_e_n_t The null statement has the form ; A null statement is useful to carry a label just before the } of a compound statement or to supply a null body to a looping statement such as _w_h_i_l_e. _1_0. _E_x_t_e_r_n_a_l _D_e_f_i_n_i_t_i_o_n_s A C program consists of a sequence of external defini- tions. An external definition declares an identifier to have storage class _e_x_t_e_r_n (by default) or perhaps static, and a specified type. The type-specifier (see ``Type Specifiers'' in ``DECLARATIONS'') may also be empty, in which case the type is taken to be _i_n_t. The scope of exter- nal definitions persists to the end of the file in which they are declared just as the effect of declarations per- sists to the end of a block. The syntax of external defini- tions is the same as that of all declarations except that only at this level may the code for functions be given. _1_0._1. _E_x_t_e_r_n_a_l _F_u_n_c_t_i_o_n _D_e_f_i_n_i_t_i_o_n_s Function definitions have the form _f_u_n_c_t_i_o_n-_d_e_f_i_n_i_t_i_o_n: _d_e_c_l-_s_p_e_c_i_f_i_e_r_s9_o_p_t8 _f_u_n_c_t_i_o_n-_d_e_c_l_a_r_a_t_o_r _f_u_n_c_t_i_o_n-_b_o_d_y The only sc-specifiers allowed among the decl- specifiers are _e_x_t_e_r_n or static; see ``Scope of Externals'' in ``SCOPE RULES'' for the distinction between them. A function declarator is similar to a declarator for a ``func- tion returning ...'' except that it lists the formal parame- ters of the function being defined. _f_u_n_c_t_i_o_n-_d_e_c_l_a_r_a_t_o_r: _d_e_c_l_a_r_a_t_o_r ( _p_a_r_a_m_e_t_e_r-_l_i_s_t9_o_p_t8 ) _p_a_r_a_m_e_t_e_r-_l_i_s_t: _i_d_e_n_t_i_f_i_e_r _i_d_e_n_t_i_f_i_e_r , _p_a_r_a_m_e_t_e_r-_l_i_s_t The function-body has the form September 2, 1987 - 37 - _f_u_n_c_t_i_o_n-_b_o_d_y: _d_e_c_l_a_r_a_t_i_o_n-_l_i_s_t9_o_p_t8 _c_o_m_p_o_u_n_d-_s_t_a_t_e_m_e_n_t 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 _i_n_t. The only storage class which may be specified is register; if it is specified, the corresponding actual parameter will be copied, if possible, into a register at the outset of the function. A simple example of a complete function definition is int max(a, b, c) int a, b, c; { int m; m = (a > b) ? a : b; return((m > c) ? m : c); } Here _i_n_t is the type-specifier; _m_a_x(_a, _b, _c) is the function-declarator; _i_n_t _a, _b, _c; is the declaration-list for the formal parameters; { ... } is the block giving the code for the statement. The C program converts all _f_l_o_a_t actual parameters to double, so formal parameters declared _f_l_o_a_t have their declaration adjusted to read _d_o_u_b_l_e. All char and short formal parameter declarations are similarly adjusted to read int. Also, since a reference to an array in any context (in particular as an actual parameter) is taken to mean a pointer to the first element of the array, declarations of formal parameters declared ``array of ...'' are adjusted to read ``pointer to ....'' _1_0._2. _E_x_t_e_r_n_a_l _D_a_t_a _D_e_f_i_n_i_t_i_o_n_s An external data definition has the form _d_a_t_a-_d_e_f_i_n_i_t_i_o_n: _d_e_c_l_a_r_a_t_i_o_n The storage class of such data may be _e_x_t_e_r_n (which is the default) or _s_t_a_t_i_c but not _a_u_t_o or register. September 2, 1987 - 38 - _1_1. _S_c_o_p_e _R_u_l_e_s 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. Com- munication among the functions of a program may be carried out both through explicit calls and through manipulation of external data. Therefore, there are two kinds of scopes to consider: first, what may be called the _l_e_x_i_c_a_l _s_c_o_p_e of an identif- ier, which is essentially the region of a program during which it may be used without drawing ``undefined identif- ier'' diagnostics; and second, the scope associated with external identifiers, which is characterized by the rule that references to the same external identifier are refer- ences to the same object. _1_1._1. _L_e_x_i_c_a_l _S_c_o_p_e 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. In all cases, however, if an identifier is explicitly declared at the head of a block, including the block consti- tuting a function, any declaration of that identifier out- side the block is suspended until the end of the block. Remember also (see ``Structure, Union, and Enumeration Declarations'' in ``DECLARATIONS'') that tags, identifiers associated with ordinary variables, and identities associ- ated 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 enum constants are in the same class as ordinary variables and follow the same scope rules. The _t_y_p_e_d_e_f 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: typedef float distance; ... { auto int distance; ... } September 2, 1987 - 39 - The _i_n_t must be present in the second declaration, or it would be taken to be a declaration with no declarators and type _d_i_s_t_a_n_c_e. _1_1._2. _S_c_o_p_e _o_f _E_x_t_e_r_n_a_l_s If a function refers to an identifier declared to be extern, then somewhere among the files or libraries consti- tuting 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. 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 iden- tifier; explicit use of extern does not change the meaning of an external declaration. In restricted environments, the use of the extern storage class takes on an additional meaning. In these environments, the explicit appearance of the extern keyword in external data declarations of identities without initial- ization 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 extern) in the set of files and libraries comprising a mult-file program. Identifiers declared _s_t_a_t_i_c at the top level in exter- nal definitions are not visible in other files. Functions may be declared _s_t_a_t_i_c. _1_2. _C_o_m_p_i_l_e_r _C_o_n_t_r_o_l _L_i_n_e_s The C compiler contains a preprocessor capable of macro substitution, conditional compilation, and inclusion of named files. Lines beginning with # communicate with this preprocessor. There may be any number of blanks and hor- izontal tabs between the # 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. _1_2._1. _T_o_k_e_n _R_e_p_l_a_c_e_m_e_n_t A compiler-control line of the form #define _i_d_e_n_t_i_f_i_e_r _t_o_k_e_n-_s_t_r_i_n_g9_o_p_t 9 September 2, 1987 - 40 - 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 #define _i_d_e_n_t_i_f_i_e_r(_i_d_e_n_t_i_f_i_e_r, ... )_t_o_k_e_n-_s_t_r_i_n_g9_o_p_t 9 where there is no space between the first identifier and the (, is a macro definition with arguments. There may be zero or more formal parameters. Subsequent instances of the first identifier followed by a (, a sequence of tokens del- imited by commas, and a ) are replaced by the token string in the definition. Each occurrence of an identifier men- tioned 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 charac- ter 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. 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 _\ at the end of the line to be continued. This facility is most valuable for definition of ``man- ifest constants,'' as in #define TABSIZE 100 int table[TABSIZE]; A control line of the form #undef _i_d_e_n_t_i_f_i_e_r causes the identifier's preprocessor definition (if any) to be forgotten. If a #defined identifier is the subject of a subsequent #define with no intervening #undef, 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 rede- fined. September 2, 1987 - 41 - _1_2._2. _F_i_l_e _I_n_c_l_u_s_i_o_n A compiler control line of the form #include "_f_i_l_e_n_a_m_e" causes the replacement of that line by the entire contents of the file _f_i_l_e_n_a_m_e. The named file is searched for first in the directory of the file containing the #include, and then in a sequence of specified or standard places. Alter- natively, a control line of the form #include <_f_i_l_e_n_a_m_e> searches only the specified or standard places and not the directory of the #include. (How the places are specified is not part of the language.) #includes may be nested. _1_2._3. _C_o_n_d_i_t_i_o_n_a_l _C_o_m_p_i_l_a_t_i_o_n A compiler control line of the form #if _r_e_s_t_r_i_c_t_e_d-_c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n checks whether the restricted-constant expression evaluates to nonzero. (Constant expressions are discussed in ``CON- STANT EXPRESSIONS''; the following additional restrictions apply here: the constant expression may not contain _s_i_z_e_o_f casts, or an enumeration constant.) A restricted constant expression may also contain the additional unary expression defined _i_d_e_n_t_i_f_i_e_r or defined( _i_d_e_n_t_i_f_i_e_r ) which evaluates to one if the identifier is currently defined in the preprocessor and zero if it is not. All currently defined identifiers in restricted- constant-expressions are replaced by their token-strings (except those identifiers modified by defined) just as in normal text. The restricted constant expression will be evaluated only after all expressions have finished. During this evaluation, all undefined (to the procedure) identif- iers evaluate to zero. September 2, 1987 - 42 - A control line of the form #ifdef _i_d_e_n_t_i_f_i_e_r checks whether the identifier is currently defined in the preprocessor; i.e., whether it has been the subject of a #_d_e_f_i_n_e control line. It is equivalent to #ifdef(_i_d_e_n_t_i_f_i_e_r). A control line of the form #ifndef _i_d_e_n_t_i_f_i_e_r checks whether the identifier is currently undefined in the preprocessor. It is equivalent to #if !defined(_i_d_e_n_t_i_f_i_e_r). All three forms are followed by an arbitrary number of lines, possibly containing a control line #else and then by a control line #endif If the checked condition is true, then any lines between #_e_l_s_e and #_e_n_d_i_f are ignored. If the checked condi- tion is false, then any lines between the test and a #_e_l_s_e or, lacking a #else, the #_e_n_d_i_f are ignored. These constructions may be nested. _1_2._4. _L_i_n_e _C_o_n_t_r_o_l For the benefit of other preprocessors which generate C programs, a line of the form #line _c_o_n_s_t_a_n_t "_f_i_l_e_n_a_m_e" causes the compiler to believe, for purposes of error diag- nostics, that the line number of the next source line is given by the constant and the current input file is named by "_f_i_l_e_n_a_m_e". If "_f_i_l_e_n_a_m_e" is absent, the remembered file name does not change. September 2, 1987 - 43 - _1_3. _I_m_p_l_i_c_i_t _D_e_c_l_a_r_a_t_i_o_n_s 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 defini- tions 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 int; if a type but no storage class is indicated, the iden- tifier is assumed to be _a_u_t_o. An exception to the latter rule is made for functions because _a_u_t_o functions do not exist. If the type of an identifier is ``function returning ...,'' it is implicitly declared to be _e_x_t_e_r_n. In an expression, an identifier followed by ( and not already declared is contextually declared to be ``function returning _i_n_t.'' _1_4. _T_y_p_e_s _R_e_v_i_s_i_t_e_d This part summarizes the operations which can be per- formed on objects of certain types. _1_4._1. _S_t_r_u_c_t_u_r_e_s _a_n_d _U_n_i_o_n_s Structures and unions may be assigned, passed as argu- ments to functions, and returned by functions. Other plau- sible operators, such as equality comparison and structure casts, are not implemented. In a reference to a structure or union member, the name on the right of the -> or the . must specify a member of the aggregate named or pointed to by the expression on the left. In general, a member of a union may not be inspected unless the value of the union has been assigned using that same member. However, one special guarantee is made by the language in order to simplify the use of unions: if a union contains several structures that share a common initial sequence and if the union currently contains one of these structures, it is permitted to inspect the common initial part of any of the contained structures. For example, the following is a legal fragment: September 2, 1987 - 44 - union { struct { int type; } n; struct { int type; int intnode; } ni; struct { int type; float floatnode; } nf; } u; ... u.nf.type = FLOAT; u.nf.floatnode = 3.14; ... if (u.n.type == FLOAT) ... sin(u.nf.floatnode) ... _1_4._2. _F_u_n_c_t_i_o_n_s There are only two things that can be done with a func- tion m, call it or take its address. If the name of a func- tion appears in an expression not in the function-name posi- tion of a call, a pointer to the function is generated. Thus, to pass one function to another, one might say int f(); ... g(f); Then the definition of _g might read g(funcp) int (*funcp)(); { ... (*funcp)(); ... } Notice that _f must be declared explicitly in the cal- ling routine since its appearance in _g(_f) was not followed by (. September 2, 1987 - 45 - _1_4._3. _A_r_r_a_y_s, _P_o_i_n_t_e_r_s, _a_n_d _S_u_b_s_c_r_i_p_t_i_n_g 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 [] is interpreted in such a way that _E_1[_E_2] is identical to *((_E_1)+_E_2)). Because of the conversion rules which apply to +, if _E_1 is an array and _E_2 an integer, then _E_1[_E_2] refers to the _E_2-_t_h member of _E_1. Therefore, despite its asym- metric appearance, subscripting is a commutative operation. A consistent rule is followed in the case of multidi- mensional arrays. If _E is an _n-dimensional array of rank ixjx...xk, then _E appearing in an expression is converted to a pointer to an (n-1)-dimensional array with rank jx...xk. If the * 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. For example, consider int x[3][5]; Here _x is a 3x5 array of integers. When _x appears in an expression, it is converted to a pointer to (the first of three) 5-membered arrays of integers. In the expression x[i], which is equivalent to *(x+i), _x is first converted to a pointer as described; then _i is converted to the type of x, which involves multiplying _i 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 sub- script, the same argument applies again; this time the result is an integer. 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. _1_4._4. _E_x_p_l_i_c_i_t _P_o_i_n_t_e_r _C_o_n_v_e_r_s_i_o_n_s Certain conversions involving pointers are permitted but have implementation-dependent aspects. They are all specified by means of an explicit type-conversion operator, see ``Unary Operators'' under``EXPRESSIONS'' and ``Type Names''under ``DECLARATIONS.'' A pointer may be converted to any of the integral types large enough to hold it. Whether an _i_n_t or _l_o_n_g is required September 2, 1987 - 46 - 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. An object of integral type may be explicitly converted to a pointer. The mapping always carries an integer con- verted from a pointer back to the same pointer but is other- wise machine dependent. 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. For example, a storage-allocation routine might accept a size (in bytes) of an object to allocate, and return a _c_h_a_r pointer; it might be used in this way. extern char *malloc(); double *dp; dp = (double *) malloc(sizeof(double)); *dp = 22.0 / 7.0; The _a_l_l_o_c must ensure (in a machine-dependent way) that its return value is suitable for conversion to a pointer to double; then the _u_s_e of the function is portable. The pointer representation on the PDP-11 corresponds to a 16-bit integer and measures bytes. The _c_h_a_r's have no alignment requirements; everything else must have an even address. 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 _d_o_u_b_l_e quantities need be aligned only on even 4-byte boundaries. Aggregates are aligned on the strictest boundary required by any of their constituents. The 3B 20 computer has 24-bit pointers placed into 32- bit quantities. Most objects are aligned on 4-byte boun- daries. Shorts are aligned in all cases on 2-byte boun- daries. Arrays of characters, all structures, ints, longs, floats, and doubles are aligned on 4-byte boundries; but structure members may be packed tighter. September 2, 1987 - 47 - _1_4._5. _C_O_N_S_T_A_N_T _E_X_P_R_E_S_S_I_O_N_S In several places C requires expressions that evaluate to a constant: after case, as array bounds, and in initial- izers. In the first two cases, the expression can involve only integer constants, character constants, casts to integral types, enumeration constants, and _s_i_z_e_o_f expres- sions, possibly connected by the binary operators + - * / % & | ^ << >> == != < > <= >= && || or by the unary operators - ~ or by the ternary operator ?: Parentheses can be used for grouping but not for func- tion calls. 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 & operator to external or static objects and to external or static arrays subscripted with a constant expression. The unary & 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. _1_5. _P_o_r_t_a_b_i_l_i_t_y _C_o_n_s_i_d_e_r_a_t_i_o_n_s 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. Purely hardware issues like word size and the proper- ties 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 implemen- tations. Some of these, particularly sign extension (con- verting 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. The number of _r_e_g_i_s_t_e_r variables that can actually be placed in registers varies from machine to machine as does September 2, 1987 - 48 - the set of valid types. Nonetheless, the compilers all do things properly for their own machine; excess or invalid _r_e_g_i_s_t_e_r declarations are ignored. Some difficulties arise only when dubious coding prac- tices are used. It is exceedingly unwise to write programs that depend on any of these properties. The order of evaluation of function arguments is not specified by the language. The order in which side effects take place is also unspecified. Since character constants are really objects of type int, 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. 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 pro- grams that do not indulge in type punning (e.g., by convert- ing an _i_n_t pointer to a _c_h_a_r pointer and inspecting the pointed-to storage) but must be accounted for when conform- ing to externally-imposed storage layouts. _1_6. _S_y_n_t_a_x _S_u_m_m_a_r_y This summary of C syntax is intended more for aiding comprehension than as an exact statement of the language. _1_6._1. _E_x_p_r_e_s_s_i_o_n_s The basic expressions are: _e_x_p_r_e_s_s_i_o_n: _p_r_i_m_a_r_y * _e_x_p_r_e_s_s_i_o_n &_l_v_a_l_u_e - _e_x_p_r_e_s_s_i_o_n ! _e_x_p_r_e_s_s_i_o_n ~ _e_x_p_r_e_s_s_i_o_n ++ _l_v_a_l_u_e --_l_v_a_l_u_e _l_v_a_l_u_e ++ _l_v_a_l_u_e -- sizeof _e_x_p_r_e_s_s_i_o_n sizeof (_t_y_p_e-_n_a_m_e) ( _t_y_p_e-_n_a_m_e ) _e_x_p_r_e_s_s_i_o_n _e_x_p_r_e_s_s_i_o_n _b_i_n_o_p _e_x_p_r_e_s_s_i_o_n _e_x_p_r_e_s_s_i_o_n ? _e_x_p_r_e_s_s_i_o_n : _e_x_p_r_e_s_s_i_o_n _l_v_a_l_u_e _a_s_g_n_o_p _e_x_p_r_e_s_s_i_o_n _e_x_p_r_e_s_s_i_o_n , _e_x_p_r_e_s_s_i_o_n September 2, 1987 - 49 - _p_r_i_m_a_r_y: _i_d_e_n_t_i_f_i_e_r _c_o_n_s_t_a_n_t _s_t_r_i_n_g ( _e_x_p_r_e_s_s_i_o_n ) _p_r_i_m_a_r_y ( _e_x_p_r_e_s_s_i_o_n-_l_i_s_t9_o_p_t8 ) _p_r_i_m_a_r_y [ _e_x_p_r_e_s_s_i_o_n ] _p_r_i_m_a_r_y . _i_d_e_n_t_i_f_i_e_r _p_r_i_m_a_r_y - _i_d_e_n_t_i_f_i_e_r _l_v_a_l_u_e: _i_d_e_n_t_i_f_i_e_r _p_r_i_m_a_r_y [ _e_x_p_r_e_s_s_i_o_n ] _l_v_a_l_u_e . _i_d_e_n_t_i_f_i_e_r _p_r_i_m_a_r_y - _i_d_e_n_t_i_f_i_e_r * _e_x_p_r_e_s_s_i_o_n ( _l_v_a_l_u_e ) The primary-expression operators () [] . - have highest priority and group left to right. The unary operators * & - ! ~ ++ -- sizeof ( _t_y_p_e-_n_a_m_e ) have priority below the primary operators but higher than any binary operator and group right to left. Binary opera- tors group left to right; they have priority decreasing as indicated below. _b_i_n_o_p: * / % + - >> << < > <= >= == != & ^ | && || The conditional operator groups right to left. Assignment operators all have the same priority and all group right to left. September 2, 1987 - 50 - _a_s_g_n_o_p: = += -= *= /= %= >>= <<= &= ^= |= The comma operator has the lowest priority and groups left to right. _1_6._2. _D_e_c_l_a_r_a_t_i_o_n_s _d_e_c_l_a_r_a_t_i_o_n: _d_e_c_l-_s_p_e_c_i_f_i_e_r_s _i_n_i_t-_d_e_c_l_a_r_a_t_o_r-_l_i_s_t9_o_p_t8 ; _d_e_c_l-_s_p_e_c_i_f_i_e_r_s: _t_y_p_e-_s_p_e_c_i_f_i_e_r _d_e_c_l-_s_p_e_c_i_f_i_e_r_s9_o_p_t 8 _s_c-_s_p_e_c_i_f_i_e_r _d_e_c_l-_s_p_e_c_i_f_i_e_r_s9_o_p_t 9 _s_c-_s_p_e_c_i_f_i_e_r: auto static extern register typedef _t_y_p_e-_s_p_e_c_i_f_i_e_r: _s_t_r_u_c_t-_o_r-_u_n_i_o_n-_s_p_e_c_i_f_i_e_r _t_y_p_e_d_e_f-_n_a_m_e _e_n_u_m-_s_p_e_c_i_f_i_e_r _b_a_s_i_c-_t_y_p_e-_s_p_e_c_i_f_i_e_r: _b_a_s_i_c-_t_y_p_e _b_a_s_i_c-_t_y_p_e _b_a_s_i_c-_t_y_p_e-_s_p_e_c_i_f_i_e_r_s _b_a_s_i_c-_t_y_p_e: char short int long unsigned float double void _e_n_u_m-_s_p_e_c_i_f_i_e_r: enum { _e_n_u_m-_l_i_s_t } enum _i_d_e_n_t_i_f_i_e_r { _e_n_u_m-_l_i_s_t } enum _i_d_e_n_t_i_f_i_e_r September 2, 1987 - 51 - _e_n_u_m-_l_i_s_t: _e_n_u_m_e_r_a_t_o_r _e_n_u_m-_l_i_s_t , _e_n_u_m_e_r_a_t_o_r _e_n_u_m_e_r_a_t_o_r: _i_d_e_n_t_i_f_i_e_r _i_d_e_n_t_i_f_i_e_r = _c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n _i_n_i_t-_d_e_c_l_a_r_a_t_o_r-_l_i_s_t: _i_n_i_t-_d_e_c_l_a_r_a_t_o_r _i_n_i_t-_d_e_c_l_a_r_a_t_o_r , _i_n_i_t-_d_e_c_l_a_r_a_t_o_r-_l_i_s_t _i_n_i_t-_d_e_c_l_a_r_a_t_o_r: _d_e_c_l_a_r_a_t_o_r _i_n_i_t_i_a_l_i_z_e_r9_o_p_t 9 _d_e_c_l_a_r_a_t_o_r: _i_d_e_n_t_i_f_i_e_r ( _d_e_c_l_a_r_a_t_o_r ) * _d_e_c_l_a_r_a_t_o_r _d_e_c_l_a_r_a_t_o_r () _d_e_c_l_a_r_a_t_o_r [ _c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n9_o_p_t8 ] _s_t_r_u_c_t-_o_r-_u_n_i_o_n-_s_p_e_c_i_f_i_e_r: struct { _s_t_r_u_c_t-_d_e_c_l-_l_i_s_t } struct _i_d_e_n_t_i_f_i_e_r { _s_t_r_u_c_t-_d_e_c_l-_l_i_s_t } struct _i_d_e_n_t_i_f_i_e_r union { _s_t_r_u_c_t-_d_e_c_l-_l_i_s_t } union _i_d_e_n_t_i_f_i_e_r { _s_t_r_u_c_t-_d_e_c_l-_l_i_s_t } union _i_d_e_n_t_i_f_i_e_r _s_t_r_u_c_t-_d_e_c_l-_l_i_s_t: _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_i_o_n _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_i_o_n _s_t_r_u_c_t-_d_e_c_l-_l_i_s_t _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_i_o_n: _t_y_p_e-_s_p_e_c_i_f_i_e_r _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_o_r-_l_i_s_t ; _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_o_r-_l_i_s_t: _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_o_r _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_o_r , _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_o_r-_l_i_s_t September 2, 1987 - 52 - _s_t_r_u_c_t-_d_e_c_l_a_r_a_t_o_r: _d_e_c_l_a_r_a_t_o_r _d_e_c_l_a_r_a_t_o_r : _c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n : _c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n _i_n_i_t_i_a_l_i_z_e_r: = _e_x_p_r_e_s_s_i_o_n = { _i_n_i_t_i_a_l_i_z_e_r-_l_i_s_t } = { _i_n_i_t_i_a_l_i_z_e_r-_l_i_s_t , } _i_n_i_t_i_a_l_i_z_e_r-_l_i_s_t: _e_x_p_r_e_s_s_i_o_n _i_n_i_t_i_a_l_i_z_e_r-_l_i_s_t , _i_n_i_t_i_a_l_i_z_e_r-_l_i_s_t { _i_n_i_t_i_a_l_i_z_e_r-_l_i_s_t } { _i_n_i_t_i_a_l_i_z_e_r-_l_i_s_t , } _t_y_p_e-_n_a_m_e: _t_y_p_e-_s_p_e_c_i_f_i_e_r _a_b_s_t_r_a_c_t-_d_e_c_l_a_r_a_t_o_r _a_b_s_t_r_a_c_t-_d_e_c_l_a_r_a_t_o_r: _e_m_p_t_y ( _a_b_s_t_r_a_c_t-_d_e_c_l_a_r_a_t_o_r ) * _a_b_s_t_r_a_c_t-_d_e_c_l_a_r_a_t_o_r _a_b_s_t_r_a_c_t-_d_e_c_l_a_r_a_t_o_r () _a_b_s_t_r_a_c_t-_d_e_c_l_a_r_a_t_o_r [ _c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n9_o_p_t8 ] _t_y_p_e_d_e_f-_n_a_m_e: _i_d_e_n_t_i_f_i_e_r _1_6._3. _S_t_a_t_e_m_e_n_t_s _c_o_m_p_o_u_n_d-_s_t_a_t_e_m_e_n_t: { _d_e_c_l_a_r_a_t_i_o_n-_l_i_s_t9_o_p_t8 _s_t_a_t_e_m_e_n_t-_l_i_s_t9_o_p_t8 } _d_e_c_l_a_r_a_t_i_o_n-_l_i_s_t: _d_e_c_l_a_r_a_t_i_o_n _d_e_c_l_a_r_a_t_i_o_n _d_e_c_l_a_r_a_t_i_o_n-_l_i_s_t _s_t_a_t_e_m_e_n_t-_l_i_s_t: _s_t_a_t_e_m_e_n_t _s_t_a_t_e_m_e_n_t _s_t_a_t_e_m_e_n_t-_l_i_s_t September 2, 1987 - 53 - _s_t_a_t_e_m_e_n_t: _c_o_m_p_o_u_n_d-_s_t_a_t_e_m_e_n_t _e_x_p_r_e_s_s_i_o_n ; if ( _e_x_p_r_e_s_s_i_o_n ) _s_t_a_t_e_m_e_n_t if ( _e_x_p_r_e_s_s_i_o_n ) _s_t_a_t_e_m_e_n_t else _s_t_a_t_e_m_e_n_t while ( _e_x_p_r_e_s_s_i_o_n ) _s_t_a_t_e_m_e_n_t do _s_t_a_t_e_m_e_n_t while ( _e_x_p_r_e_s_s_i_o_n ) ; for (_e_x_p9_o_p_t8;_e_x_p9_o_p_t8;_e_x_p9_o_p_t8) _s_t_a_t_e_m_e_n_t switch ( _e_x_p_r_e_s_s_i_o_n ) _s_t_a_t_e_m_e_n_t case _c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n : _s_t_a_t_e_m_e_n_t default : _s_t_a_t_e_m_e_n_t break ; continue ; return ; return _e_x_p_r_e_s_s_i_o_n ; goto _i_d_e_n_t_i_f_i_e_r ; _i_d_e_n_t_i_f_i_e_r : _s_t_a_t_e_m_e_n_t ; _1_6._4. _E_x_t_e_r_n_a_l _d_e_f_i_n_i_t_i_o_n_s _p_r_o_g_r_a_m: _e_x_t_e_r_n_a_l-_d_e_f_i_n_i_t_i_o_n _e_x_t_e_r_n_a_l-_d_e_f_i_n_i_t_i_o_n _p_r_o_g_r_a_m _e_x_t_e_r_n_a_l-_d_e_f_i_n_i_t_i_o_n: _f_u_n_c_t_i_o_n-_d_e_f_i_n_i_t_i_o_n _d_a_t_a-_d_e_f_i_n_i_t_i_o_n _f_u_n_c_t_i_o_n-_d_e_f_i_n_i_t_i_o_n: _d_e_c_l-_s_p_e_c_i_f_i_e_r9_o_p_t8 _f_u_n_c_t_i_o_n-_d_e_c_l_a_r_a_t_o_r _f_u_n_c_t_i_o_n-_b_o_d_y _f_u_n_c_t_i_o_n-_d_e_c_l_a_r_a_t_o_r: _d_e_c_l_a_r_a_t_o_r ( _p_a_r_a_m_e_t_e_r-_l_i_s_t9_o_p_t8 ) _p_a_r_a_m_e_t_e_r-_l_i_s_t: _i_d_e_n_t_i_f_i_e_r _i_d_e_n_t_i_f_i_e_r , _p_a_r_a_m_e_t_e_r-_l_i_s_t _f_u_n_c_t_i_o_n-_b_o_d_y: _d_e_c_l_a_r_a_t_i_o_n-_l_i_s_t9_o_p_t8 _c_o_m_p_o_u_n_d-_s_t_a_t_e_m_e_n_t _d_a_t_a-_d_e_f_i_n_i_t_i_o_n: extern _d_e_c_l_a_r_a_t_i_o_n ; static _d_e_c_l_a_r_a_t_i_o_n ; September 2, 1987 - 54 - _1_7. _P_r_e_p_r_o_c_e_s_s_o_r #define _i_d_e_n_t_i_f_i_e_r _t_o_k_e_n-_s_t_r_i_n_g9_o_p_t 8 #define _i_d_e_n_t_i_f_i_e_r(_i_d_e_n_t_i_f_i_e_r,...)_t_o_k_e_n-_s_t_r_i_n_g9_o_p_t 8 #undef _i_d_e_n_t_i_f_i_e_r #include "_f_i_l_e_n_a_m_e" #include <_f_i_l_e_n_a_m_e> #if _r_e_s_t_r_i_c_t_e_d-_c_o_n_s_t_a_n_t-_e_x_p_r_e_s_s_i_o_n #ifdef _i_d_e_n_t_i_f_i_e_r #ifndef _i_d_e_n_t_i_f_i_e_r #else #endif #line _c_o_n_s_t_a_n_t "_f_i_l_e_n_a_m_e" September 2, 1987