.ul 7. Expressions .et The precedence of expression operators is the same as the order of the major subsections of this section (highest precedence first). Thus the expressions referred to as the operands of \fG+\fR (\(sc7.4) are those expressions defined in \(sc\(sc7.1_7.3. Within each subsection, 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 is summarized in an appendix. .pg 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. .ms 7.1 Primary expressions .et Primary expressions involving \fG.\fR^, \fG\(mi>\fR, subscripting, and function calls group left to right. .ms 7.1.1 \fIidentifier\fR .et An identifier is a primary expression, provided it has been suitably declared as discussed below. Its type is specified by its declaration. However, if the type of the identifier is ``array of .^.^.'', then the value of the identifier-expression is a pointer to the first object in the array, and the type of the expression is ``pointer to .^.^.''. Moreover, an array identifier is not an lvalue expression. .pg Likewise, an identifier which is declared ``function returning .^.^.'', when used except in the function-name position of a call, is converted to ``pointer to function returning .^.^.''. .ms 7.1.2 \fIconstant\fR .et A decimal, octal, character, or floating constant is a primary expression. Its type is \fGint\fR in the first three cases, \fGdouble\fR in the last. .ms 7.1.3 \fIstring\fR .et A string is a primary expression. Its type is originally ``array of \fGchar\fR''; but following the same rule as in \(sc7.1.1 for identifiers, this is modified to ``pointer to \fGchar\fR'' and the result is a pointer to the first character in the string. .ms 7.1.4 \fG(\fI expression \fG)\fR .et 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. .ms 7.1.5 \fIprimary-expression\fG [\fI expression \fG]\fR .et 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 \fGint\fR, and the type of the result is ``^.^.^.^''. The expression ``E1[E2]'' is identical (by definition) to ``\**^(^^(^E1^)^+^(^E2^)^^)^''. All the clues needed to understand this notation are contained in this section together with the discussions in \(sc\(sc 7.1.1, 7.2.1, and 7.4.1 on identifiers, \fG\**\fR, and \fG+\fR respectively; \(sc14.3 below summarizes the implications. .ms 7.1.6 \fIprimary-expression \fG( \fIexpression-list\*(op \fG) .et A function call is a primary expression followed by parentheses containing a possibly empty, comma-separated list of expressions which constitute the actual arguments to the function. The primary expression must be of type ``function returning .^.^.'', and the result of the function call is of type ``^.^.^.^''. As indicated below, a hitherto unseen identifier followed immediately by a left parenthesis is contextually declared to represent a function returning an integer; thus in the most common case, integer-valued functions need not be declared. .pg Any actual arguments of type \fGfloat\fR are converted to \fGdouble\fR before the call; any of type \fGchar\fR are converted to \fGint\fR. .pg 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 possibly affect the values of the actual parameters. On the other hand, it is perfectly possible to pass a pointer on the understanding that the function may change the value of the object to which the pointer points. .pg Recursive calls to any function are permissible. .ms 7.1.7 \fIprimary-lvalue \fG.\fI member-of-structure\fR .et An lvalue expression followed by a dot followed by the name of a member of a structure is a primary expression. The object referred to by the lvalue is assumed to have the same form as the structure containing the structure member. The result of the expression is an lvalue appropriately offset from the origin of the given lvalue whose type is that of the named structure member. The given lvalue is not required to have any particular type. .pg Structures are discussed in \(sc8.5. .ms 7.1.8 \fIprimary-expression \fG\(mi>\fI member-of-structure\fR .et The primary-expression is assumed to be a pointer which points to an object of the same form as the structure of which the member-of-structure is a part. The result is an lvalue appropriately offset from the origin of the pointed-to structure whose type is that of the named structure member. The type of the primary-expression need not in fact be pointer; it is sufficient that it be a pointer, character, or integer. .pg Except for the relaxation of the requirement that E1 be of pointer type, the expression ``E1\(mi>MOS'' is exactly equivalent to ``(\**E1).MOS''. .ms 7.2 Unary operators .et Expressions with unary operators group right-to-left. .ms 7.2.1 \fG\**\fI expression\fR .et The unary \fG\**\fR operator means .ft I indirection: .ft R the expression must be a pointer, and the result is an lvalue referring to the object to which the expression points. If the type of the expression is ``pointer to .^.^.'', the type of the result is ``^.^.^.^''. .ms 7.2.2 \fG&\fI lvalue-expression\fR .et The result of the unary \fG&\fR operator is a pointer to the object referred to by the lvalue-expression. If the type of the lvalue-expression is ``^.^.^.^'', the type of the result is ``pointer to .^.^.''. .ms 7.2.3 \fG\(mi\fI expression\fR .et The result is the negative of the expression, and has the same type. The type of the expression must be \fGchar\fR, \fGint\fR, \fGfloat\fR, or \fGdouble\fR. .ms 7.2.4 \fG!\fI expression\fR .et The result of the logical negation operator \fG!\fR is 1 if the value of the expression is 0, 0 if the value of the expression is non-zero. The type of the result is \fGint\fR. This operator is applicable only to \fGint\fRs or \fGchar\fRs. .ms 7.2.5 \fG\*~\fI expression\fR .et The \*~ operator yields the one's complement of its operand. The type of the expression must be \fGint\fR or \fGchar\fR, and the result is \fGint\fR. .ms 7.2.6 ++ \fIlvalue-expression\fR .et The object referred to by the lvalue expression is incremented. The value is the new value of the lvalue expression and the type is the type of the lvalue. If the expression is \fGint\fR or \fGchar\fR, it is incremented by 1; if it is a pointer to an object, it is incremented by the length of the object. ++ is applicable only to these types. (Not, for example, to \fGfloat\fR or \fGdouble\fR.) .ms 7.2.7 \fR\(mi\(mi\fI lvalue-expression\fR .et The object referred to by the lvalue expression is decremented analogously to the ++ operator. .ms 7.2.8 \fIlvalue-expression ++ .et The result is the value of the object referred to by the lvalue expression. After the result is noted, the object referred to by the lvalue is incremented in the same manner as for the prefix ++ operator: by 1 for an \fGint\fR or \fGchar\fR, by the length of the pointed-to object for a pointer. The type of the result is the same as the type of the lvalue-expression. .ms 7.2.9 \fIlvalue-expression \(mi\(mi .et The result of the expression is the value of the object referred to by the the lvalue expression. After the result is noted, the object referred to by the lvalue expression is decremented in a way analogous to the postfix ++ operator. .ms 7.2.10 \fGsizeof \fIexpression .et The \fGsizeof\fR operator yields the size, in bytes, of its operand. 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 integer 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. .ms 7.3 Multiplicative operators .et The multiplicative operators \fG\**\fR, \fG/\fR, and \fG%\fR group left-to-right. .ms 7.3.1 \fIexpression\fG \** \fIexpression\fR .et The binary \fG\**\fR operator indicates multiplication. If both operands are \fGint\fR or \fGchar\fR, the result is \fGint\fR; if one is \fGint\fR or \fGchar\fR and one \fGfloat\fR or \fGdouble\fR, the former is converted to \fGdouble\fR, and the result is \fGdouble\fR; if both are \fGfloat\fR or \fGdouble\fR, the result is \fGdouble\fR. No other combinations are allowed. .ms 7.3.2 \fIexpression \fG/\fI expression\fR .et The binary \fG/\fR operator indicates division. The same type considerations as for multiplication apply. .ms 7.3.3 \fIexpression \fG%\fI expression\fR .et The binary \fG%\fR operator yields the remainder from the division of the first expression by the second. Both operands must be \fGint\fR or \fGchar\fR, and the result is \fGint\fR. In the current implementation, the remainder has the same sign as the dividend. .ms 7.4 Additive operators .et The additive operators \fG+\fR and \fG\(mi\fR group left-to-right. .ms 7.4.1 \fIexpression \fG+\fI expression\fR .et The result is the sum of the expressions. If both operands are \fGint\fR or \fGchar\fR, the result is \fGint\fR. If both are \fGfloat\fR or \fGdouble\fR, the result is \fGdouble\fR. If one is \fGchar\fR or \fGint\fR and one is \fGfloat\fR or \fGdouble\fR, the former is converted to \fGdouble\fR and the result is \fGdouble\fR. If an \fGint\fR or \fGchar\fR is added to a pointer, the former is converted by multiplying it by the length of the object to which the pointer points and the result is a pointer of the same type as the original pointer. Thus if P is a pointer to an object, the expression ``P+1'' is a pointer to another object of the same type as the first and immediately following it in storage. .pg No other type combinations are allowed. .ms 7.4.2 \fIexpression \fG\(mi \fIexpression\fR .et The result is the difference of the operands. If both operands are \fGint\fR, \fGchar\fR, \fGfloat\fR, or \fGdouble\fR, the same type considerations as for \fG+\fR apply. If an \fGint\fR or \fGchar\fR is subtracted from a pointer, the former is converted in the same way as explained under \fG+\fR above. .pg If two pointers to objects of the same type are subtracted, the result is converted (by division by the length of the object) to an \fGint\fR 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. .ms 7.5 Shift operators .et The shift operators \fG<<\fR and \fG>>\fR group left-to-right. .ms 7.5.1 \fIexpression \fG<< \fIexpression\fR .br 7.5.2 \fIexpression \fG>> \fIexpression\fR .et Both operands must be \fGint\fR or \fGchar\fR, and the result is \fGint\fR. The second operand should be non-negative. The value of ``E1<>E2'' is E1 (interpreted as a two's complement, 16-bit quantity) arithmetically right-shifted E2 bit positions. Vacated bits are filled by a copy of the sign bit of E1. [Note: the use of arithmetic rather than logical shift does not survive transportation between machines.] .ms 7.6 Relational operators .et The relational operators group left-to-right, but this fact is not very useful; ``a\fI expression\fR .br .ne 4 7.6.3 \fIexpression \fG<=\fI expression\fR .br .ne 4 7.6.4 \fIexpression \fG>=\fI expression\fR .et 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. Operand conversion is exactly the same as for the \fG+\fR operator except that pointers of any kind may be compared; the result in this case depends on the relative locations in storage of the pointed-to objects. It does not seem to be very mean$ing$ful to compare pointers with integers other than 0. .ms .ti 0 7.7 Equality operators .et .ne 4 .ti 0 7.7.1 \fIexpression \fG==\fI expression\fR .br .ne 4 7.7.2 \fIexpression \fG!=\fI expression\fR .et The \fG==\fR (equal to) and the \fG!=\fR (not equal to) operators are exactly analogous to the relational operators except for their lower precedence. (Thus ``a> \fIexpression\fR .br 7.14.8 \fIlvalue \fG=<< \fIexpression\fR .br 7.14.9 \fIlvalue \fG=& \fIexpression\fR .br .tr ^^ 7.14.10 \fIlvalue \fG=^ \fIexpression\fR .br .tr ^\| 7.14.11 \fIlvalue \fG=^\(or \fIexpression\fR .et The behavior of an expression of the form ``E1@=op@E2'' may be inferred by taking it as equivalent to ``E1@=@E1@op@E2''; however, E1 is evaluated only once. Moreover, expressions like ``i@=+@p'' in which a pointer is added to an integer, are forbidden. .ms 7.15 \fIexpression \fG,\fI expression\fR .et A pair of expressions separated by a comma is evaluated left-to-right and the value of the left expression is discarded. The type and value of the result are the type and value of the right operand. This operator groups left-to-right. It should be avoided in situations where comma is given a special meaning, for example in actual arguments to function calls (\(sc7.1.6) and lists of initializers (\(sc10.2).