2194 lines
86 KiB
HTML
2194 lines
86 KiB
HTML
<HTML><HEAD><TITLE>Expressions</TITLE></HEAD><BODY BGCOLOR="#FFFFFF">
|
||
|
||
<H1><A NAME="Expressions">Expressions</A></H1><HR>
|
||
|
||
<P><B><A HREF="#Expression Subcontexts">Expression Subcontexts</A>
|
||
· <A HREF="#Classes of Expressions">Classes of Expressions</A>
|
||
· <A HREF="#Class Conversions">Class Conversions</A>
|
||
· <A HREF="#Type Conversions">Type Conversions</A>
|
||
· <A HREF="#Promoting">Promoting</A>
|
||
· <A HREF="#Balancing">Balancing</A>
|
||
· <A HREF="#Assigning and Type Casting">Assigning and Type Casting</A>
|
||
· <A HREF="#Changing Representations">Changing Representations</A>
|
||
· <A HREF="#Pointer Arithmetic">Pointer Arithmetic</A>
|
||
· <A HREF="#Reading Expressions">Reading Expressions</A>
|
||
· <A HREF="#Grouping">Grouping</A>
|
||
· <A HREF="#Operator Summary">Operator Summary</A>
|
||
· <A HREF="#Order of Evaluation">Order of Evaluation</A>
|
||
</B></P>
|
||
|
||
<P><B><A HREF="#Add Assign">Add Assign</A>
|
||
· <A HREF="#Add">Add</A>
|
||
· <A HREF="#Address of">Address of</A>
|
||
· <A HREF="#Assignment">Assignment</A>
|
||
· <A HREF="#Bitwise AND Assign">Bitwise AND Assign</A>
|
||
· <A HREF="#Bitwise AND">Bitwise AND</A>
|
||
· <A HREF="#Bitwise Exclusive OR Assign">Bitwise Exclusive OR Assign</A>
|
||
· <A HREF="#Bitwise Exclusive OR">Bitwise Exclusive OR</A>
|
||
· <A HREF="#Bitwise Inclusive OR Assign">Bitwise Inclusive OR Assign</A>
|
||
· <A HREF="#Bitwise Inclusive OR">Bitwise Inclusive OR</A>
|
||
· <A HREF="#Bitwise NOT">Bitwise NOT</A>
|
||
· <A HREF="#Comma">Comma</A>
|
||
· <A HREF="#Conditional">Conditional</A>
|
||
· <A HREF="#Divide Assign">Divide Assign</A>
|
||
· <A HREF="#Divide">Divide</A>
|
||
· <A HREF="#Equals">Equals</A>
|
||
· <A HREF="#Function Call">Function Call</A>
|
||
· <A HREF="#Greater Than Or Equal">Greater Than Or Equal</A>
|
||
· <A HREF="#Greater Than">Greater Than</A>
|
||
· <A HREF="#Indirection">Indirection</A>
|
||
· <A HREF="#Left Shift Assign">Left Shift Assign</A>
|
||
· <A HREF="#Left Shift">Left Shift</A>
|
||
· <A HREF="#Less Than Or Equal">Less Than Or Equal</A>
|
||
· <A HREF="#Less Than">Less Than</A>
|
||
· <A HREF="#Logical AND">Logical AND</A>
|
||
· <A HREF="#Logical NOT">Logical NOT</A>
|
||
· <A HREF="#Logical OR">Logical OR</A>
|
||
· <A HREF="#Minus"></A>
|
||
· <A HREF="#Multiply Assign">Multiply Assign</A>
|
||
· <A HREF="#Multiply">Multiply</A>
|
||
· <A HREF="#Not Equals">Not Equals</A>
|
||
· <A HREF="#Plus">Plus</A>
|
||
· <A HREF="#Point at">Point at</A>
|
||
· <A HREF="#Postdecrement">Postdecrement</A>
|
||
· <A HREF="#Postincrement">Postincrement</A>
|
||
· <A HREF="#Predecrement">Predecrement</A>
|
||
· <A HREF="#Preincrement">Preincrement</A>
|
||
· <A HREF="#Remainder Assign">Remainder Assign</A>
|
||
· <A HREF="#Remainder">Remainder</A>
|
||
· <A HREF="#Right Shift Assign">Right Shift Assign</A>
|
||
· <A HREF="#Right Shift">Right Shift</A>
|
||
· <A HREF="#Select">Select</A>
|
||
· <A HREF="#sizeof operator">sizeof</A>
|
||
· <A HREF="#Subscript">Subscript</A>
|
||
· <A HREF="#Subtract Assign">Subtract Assign</A>
|
||
· <A HREF="#Subtract">Subtract</A>
|
||
· <A HREF="#Type Cast">Type Cast</A>
|
||
</B></P>
|
||
<HR>
|
||
|
||
<P>You write <B>expressions</B> to determine values, to alter values stored
|
||
in objects, and to call functions that perform input and output. In
|
||
fact, you express all computations in the program by writing expressions.</P>
|
||
|
||
<P>The translator itself must evaluate some of the expressions you write
|
||
to determine properties of the program. The translator or the target
|
||
environment must evaluate other expressions prior to
|
||
<A HREF="lib_over.html#program startup" tppabs="http://ccs.ucsd.edu/c/lib_over.html#program startup">program startup</A>
|
||
to determine the initial values stored in objects with
|
||
<A HREF="declare.html#static duration" tppabs="http://ccs.ucsd.edu/c/declare.html#static duration">static duration</A>.
|
||
The program evaluates the remaining expressions when it executes.</P>
|
||
|
||
<P>This document describes the different
|
||
<A HREF="#Classes of Expressions">classes of expressions</A>
|
||
and the restrictions on each class. It presents the common rules for
|
||
writing all expressions, determining their types, and computing their
|
||
values. It also discusses the constraints on the
|
||
<A HREF="function.html#flow of control" tppabs="http://ccs.ucsd.edu/c/function.html#flow of control">flow of control</A> through
|
||
an expression.</P>
|
||
|
||
<H2><A NAME="Expression Subcontexts">Expression Subcontexts</A></H2>
|
||
|
||
<P>Within a statement or declaration, every full expression that
|
||
you write inhabits one of three contexts:</P>
|
||
|
||
<UL>
|
||
<LI>a <A HREF="function.html#test context" tppabs="http://ccs.ucsd.edu/c/function.html#test context">test context</A></LI>
|
||
|
||
<LI>a <A HREF="function.html#value context" tppabs="http://ccs.ucsd.edu/c/function.html#value context">value context</A></LI>
|
||
|
||
<LI>a <A HREF="function.html#side-effects context" tppabs="http://ccs.ucsd.edu/c/function.html#side-effects context">side-effects
|
||
context</A></LI>
|
||
</UL>
|
||
|
||
<P>More generally, however, every full expression or subexpression
|
||
that you write inhabits one of four
|
||
<B><A NAME="expression subcontext">expression subcontexts</A></B>,
|
||
depending on its goal:</P>
|
||
|
||
<UL>
|
||
<LI>an <A HREF="#rvalue subcontext">rvalue subcontext</A>,
|
||
which includes test and value contexts
|
||
|
||
<LI>an <A HREF="#lvalue subcontext">lvalue subcontext</A></LI>
|
||
|
||
<LI>a <A HREF="#function-designator subcontext">function-designator
|
||
subcontext</A></LI>
|
||
|
||
<LI>a <A HREF="#side-effects subcontext">side-effects
|
||
subcontext</A></LI>
|
||
</UL>
|
||
|
||
<P>An <B><A NAME="rvalue subcontext">rvalue subcontext</A></B>
|
||
specifies a value that has an
|
||
<A HREF="types.html#object types" tppabs="http://ccs.ucsd.edu/c/types.html#object types">object type</A> other than an
|
||
<A HREF="types.html#Array Types" tppabs="http://ccs.ucsd.edu/c/types.html#Array Types">array type</A>.
|
||
You create an rvalue subcontext wherever
|
||
you need to specify a test or value to the translator,
|
||
determine an initial value prior to
|
||
<A HREF="lib_over.html#program startup" tppabs="http://ccs.ucsd.edu/c/lib_over.html#program startup">program startup</A>
|
||
or compute a value when the program executes.</P>
|
||
|
||
<P>An <B><A NAME="lvalue subcontext">lvalue subcontext</A></B>
|
||
designates an object, but its expression
|
||
can have either an object type or an incomplete type. You create an
|
||
lvalue subcontext wherever you need to access the value stored in
|
||
an object, alter the stored value, or determine the address of the
|
||
object. (If the type is incomplete, you can determine only the address
|
||
of the object.)</P>
|
||
|
||
<P>A <B><A NAME="function-designator subcontext">function-designator
|
||
subcontext</A></B> designates a function. Hence,
|
||
its expression has a function type. You create a function-designator
|
||
subcontext wherever you need to
|
||
call a function or determine its address.</P>
|
||
|
||
<P>A <B><A NAME="side-effects subcontext">side-effects
|
||
subcontext</A></B> specifies no value and designates
|
||
no object or function. Hence, its expression can have a
|
||
<A HREF="types.html#void types" tppabs="http://ccs.ucsd.edu/c/types.html#void types"><I>void</I> type</A>.
|
||
You create a side-effects subcontext when you need to cause only side
|
||
effects.</P>
|
||
|
||
<P>For example, consider the following code sequence:</P>
|
||
|
||
<PRE>
|
||
void f(int);
|
||
int x;
|
||
f(x = 3);</PRE>
|
||
|
||
<P>In the last line:</P>
|
||
|
||
<UL>
|
||
<LI><CODE>f</CODE> is in a function-designator subcontext</LI>
|
||
|
||
<LI><CODE>x</CODE> is in an lvalue subcontext</LI>
|
||
|
||
<LI><CODE>3</CODE> and <CODE>x = 3</CODE> are both in rvalue subcontexts</LI>
|
||
|
||
<LI><CODE>f(x = 3)</CODE> is in a side-effects subcontext</LI>
|
||
</UL>
|
||
|
||
<H2><A NAME="Classes of Expressions">Classes of Expressions</A></H2>
|
||
|
||
<P>Every expression that you write belongs to
|
||
one of several <B>expression classes</B>,
|
||
depending upon its form. Four of these classes are closely
|
||
associated with the four
|
||
<A HREF="#Expression Subcontexts">expression subcontexts</A>:</P>
|
||
|
||
<UL>
|
||
<LI>An <B><A NAME="rvalue expression">rvalue expression</A></B> has an
|
||
<A HREF="types.html#object types" tppabs="http://ccs.ucsd.edu/c/types.html#object types">object type</A> other than an
|
||
<A HREF="types.html#Array Types" tppabs="http://ccs.ucsd.edu/c/types.html#Array Types">array type</A>.</LI>
|
||
|
||
<LI>An <B><A NAME="lvalue expression">lvalue expression</A></B>
|
||
designates an object and has an object type or an
|
||
<A HREF="types.html#Incomplete Types" tppabs="http://ccs.ucsd.edu/c/types.html#Incomplete Types">incomplete type</A>.</LI>
|
||
|
||
<LI>A <B><A NAME="function-designator expression">function-designator
|
||
expression</A></B> has a
|
||
<A HREF="types.html#Function Types" tppabs="http://ccs.ucsd.edu/c/types.html#Function Types">function type</A>.</LI>
|
||
|
||
<LI>A <B><A NAME="void expression">void expression</A></B> has a
|
||
<A HREF="types.html#void types" tppabs="http://ccs.ucsd.edu/c/types.html#void types"><I>void</I> type</A>.</LI>
|
||
</UL>
|
||
|
||
<P>The first two of these classes have a number of subclasses.
|
||
For instance, an arbitrary rvalue expression can be evaluated only
|
||
by the program when it executes. One connotation of the term ``rvalue
|
||
expression'' is that you cannot write such an expression where
|
||
the translator must be able to determine its value before the program
|
||
executes. Four subclasses of rvalue expressions, however, have a value
|
||
that the translator or the target environment can determine prior
|
||
to program startup:</P>
|
||
|
||
<UL>
|
||
<LI>an <A HREF="#address constant expression">address constant
|
||
expression</A></LI>
|
||
|
||
<LI>an <A HREF="#arithmetic constant expression">arithmetic constant
|
||
expression</A></LI>
|
||
|
||
<LI>an <A HREF="#integer constant expression">integer constant
|
||
expression</A></LI>
|
||
|
||
<LI>a <A HREF="preproc.html#if expression" tppabs="http://ccs.ucsd.edu/c/preproc.html#if expression">#if expression</A></LI>
|
||
</UL>
|
||
|
||
<P>An <B><A NAME="address constant expression">address constant
|
||
expression</A></B> specifies a value that has a
|
||
<A HREF="types.html#Pointer Types" tppabs="http://ccs.ucsd.edu/c/types.html#Pointer Types">pointer type</A>
|
||
and that the translator or target environment can determine prior to
|
||
<A HREF="lib_over.html#program startup" tppabs="http://ccs.ucsd.edu/c/lib_over.html#program startup">program startup</A>.
|
||
Therefore, the expression must not cause
|
||
<A HREF="function.html#side effects" tppabs="http://ccs.ucsd.edu/c/function.html#side effects">side effects</A>.
|
||
You must not write subexpressions with a
|
||
<A HREF="types.html#void types" tppabs="http://ccs.ucsd.edu/c/types.html#void types"><I>void</I> type</A>.
|
||
(You cannot write a
|
||
<I><A HREF="#Function Call">function call</A>,
|
||
<A HREF="#Assigning and Type Casting">assigning</A>, or
|
||
<A HREF="#Comma"><I>comma</I></A> operator,
|
||
except as part of the operand of a
|
||
<A HREF="#sizeof operator"><I>sizeof</I></A> operator.)
|
||
You write address constant expressions to specify
|
||
the initial values stored in objects of pointer type with
|
||
<A HREF="declare.html#static duration" tppabs="http://ccs.ucsd.edu/c/declare.html#static duration">static duration</A>.</P>
|
||
|
||
<P>For example:</P>
|
||
|
||
<PRE>
|
||
extern int first;
|
||
static int *pf = &first; <B>&first is address constant</B></PRE>
|
||
|
||
<P>An <B><A NAME="arithmetic constant expression">arithmetic constant
|
||
expression</A></B> specifies a value that has an
|
||
<A HREF="types.html#Arithmetic Types" tppabs="http://ccs.ucsd.edu/c/types.html#Arithmetic Types">arithmetic type</A>
|
||
and that the translator or target environment can determine prior to
|
||
<A HREF="lib_over.html#program startup" tppabs="http://ccs.ucsd.edu/c/lib_over.html#program startup">program startup</A>.
|
||
Therefore, the expression must not cause
|
||
<A HREF="function.html#side effects" tppabs="http://ccs.ucsd.edu/c/function.html#side effects">side effects</A>.
|
||
You must write only subexpressions that have arithmetic type.
|
||
(You cannot write a
|
||
<I><A HREF="#Function Call">function call</A>,
|
||
<A HREF="#Assigning and Type Casting">assiging</A>, or
|
||
<A HREF="#Comma"><I>comma</I></A> operator,
|
||
except as part of the operand of a
|
||
<A HREF="#sizeof operator"><I>sizeof</I></A> operator.)
|
||
You write arithmetic constant expressions to specify the
|
||
initial values stored in objects of arithmetic type with
|
||
<A HREF="declare.html#static duration" tppabs="http://ccs.ucsd.edu/c/declare.html#static duration">static duration</A>.</P>
|
||
|
||
<P>For example:</P>
|
||
|
||
<PRE>
|
||
extern int counter = 0;
|
||
static int flt_bits = 6 / 0.30103 + 0.5;
|
||
static int ret_bytes = sizeof f();</PRE>
|
||
|
||
<P>An <B><A NAME="integer constant expression">integer constant
|
||
expression</A></B> specifies a value that has an
|
||
<A HREF="types.html#integer types" tppabs="http://ccs.ucsd.edu/c/types.html#integer types">integer type</A> and that
|
||
the translator can determine at the point in
|
||
the program where you write the expression.
|
||
The same restrictions apply as for
|
||
<A HREF="#arithmetic constant expression">arithmetic constant
|
||
expressions</A>. In addition, you must
|
||
write only subexpressions that have integer type.
|
||
You can, however, write a
|
||
<A HREF="#floating-point constant">floating-point constant</A>
|
||
as the operand of an integer
|
||
<A HREF="#Type Cast"><I>type cast</I></A> operator.
|
||
You write integer constant expressions to specify:</P>
|
||
|
||
<UL>
|
||
<LI>the value associated with a
|
||
<A HREF="function.html#Case Label" tppabs="http://ccs.ucsd.edu/c/function.html#Case Label"><I>case</I> label</A></LI>
|
||
|
||
<LI>the value of an
|
||
<A HREF="types.html#enumeration constants" tppabs="http://ccs.ucsd.edu/c/types.html#enumeration constants">enumeration constants</A></LI>
|
||
|
||
<LI>the repetition count in an
|
||
<A HREF="syntax.html#array decoration" tppabs="http://ccs.ucsd.edu/c/syntax.html#array decoration">array decoration</A>within a
|
||
<A HREF="syntax.html#Declarators" tppabs="http://ccs.ucsd.edu/c/syntax.html#Declarators">declarator</A></LI>
|
||
|
||
<LI>the number of bits in a
|
||
<A HREF="syntax.html#Object Initializers and Bitfield Specifications" tppabs="http://ccs.ucsd.edu/c/syntax.html#Object Initializers and Bitfield Specifications">bitfield
|
||
specification</A></LI>
|
||
</UL>
|
||
|
||
<P>For example:</P>
|
||
|
||
<PRE>
|
||
extern int a[20], a_copy[sizeof a / sizeof a[0]];
|
||
enum {red = 1, green = 4, blue = 16} color;</PRE>
|
||
|
||
<P>A <A HREF="preproc.html#if expression" tppabs="http://ccs.ucsd.edu/c/preproc.html#if expression">#if expression</A>
|
||
specifies a value that can be determined by an
|
||
<A HREF="preproc.html#if directive" tppabs="http://ccs.ucsd.edu/c/preproc.html#if directive"><I>if</I></A> or
|
||
<A HREF="preproc.html#elif directive" tppabs="http://ccs.ucsd.edu/c/preproc.html#elif directive"><I>elif</I> directive</A>.
|
||
After preprocessing replaces
|
||
all names within the expression, the same restrictions apply as for
|
||
<A HREF="#integer constant expression">integer constant
|
||
expressions</A>.</P>
|
||
|
||
<P>For example:</P>
|
||
|
||
<PRE>
|
||
#if __STDC__ && 32767 < INT_MAX</PRE>
|
||
|
||
<P><A HREF="#lvalue expression">Lvalue expressions</A>
|
||
fall into one of four subclasses:</P>
|
||
|
||
<UL>
|
||
<LI>an <A HREF="#accessible lvalue expression">accessible lvalue
|
||
expression</A></LI>
|
||
|
||
<LI>a <A HREF="#modifiable lvalue expression">modifiable lvalue
|
||
expression</A></LI>
|
||
|
||
<LI>an <A HREF="#array lvalue expression">array lvalue expression</A></LI>
|
||
|
||
<LI>an <A HREF="#incomplete non-array lvalue expression">incomplete
|
||
non-array lvalue expression</A></LI>
|
||
</UL>
|
||
|
||
<P>An <B><A NAME="accessible lvalue expression">accessible lvalue
|
||
expression</A></B> designates an object that has an
|
||
<A HREF="types.html#object types" tppabs="http://ccs.ucsd.edu/c/types.html#object types">object type</A> other than an
|
||
<A HREF="types.html#Array Types" tppabs="http://ccs.ucsd.edu/c/types.html#Array Types">array type</A>. Hence, you can access the
|
||
value stored in the object.</P>
|
||
|
||
<P>For example:</P>
|
||
|
||
<PRE>
|
||
static const struct complex imag = {0, 1};
|
||
return (imag); <B>imag is accessible lvalue</B></PRE>
|
||
|
||
<P>A <B><A NAME="modifiable lvalue expression">modifiable lvalue
|
||
expression</A></B> designates an object that has
|
||
<A HREF="types.html#object types" tppabs="http://ccs.ucsd.edu/c/types.html#object types">object type</A> other than an
|
||
<A HREF="types.html#Array Types" tppabs="http://ccs.ucsd.edu/c/types.html#Array Types">array type</A>
|
||
or a <I>const</I> type. Hence, you can alter
|
||
the value stored in the object.</P>
|
||
|
||
<P>For example:</P>
|
||
|
||
<PRE>
|
||
static int next_no = 0;
|
||
return ++next_no; <B>next_no is modifiable lvalue</B></PRE>
|
||
|
||
<P>An <B><A NAME="array lvalue expression">array lvalue
|
||
expression</A></B> designates an object that has an
|
||
<A HREF="types.html#Array Types" tppabs="http://ccs.ucsd.edu/c/types.html#Array Types">array type</A>. The type can be
|
||
<A HREF="types.html#Incomplete Types" tppabs="http://ccs.ucsd.edu/c/types.html#Incomplete Types">incomplete</A>.
|
||
You often write expressions that implicitly
|
||
<A HREF="#context conversions">convert</A> an array lvalue expression to an
|
||
<A HREF="#rvalue expression">rvalue expression</A> of a
|
||
<A HREF="types.html#Pointer Types" tppabs="http://ccs.ucsd.edu/c/types.html#Pointer Types">pointer type</A>.
|
||
You can also take the address of an array lvalue expression.
|
||
For example:</P>
|
||
|
||
<PRE>
|
||
static int bmask[] = {1, 8, 2, 4};
|
||
int (*pb)[] = &bmask; <B>&bmask is pointer to array</B>
|
||
y = arg & bmask[i]; <B>bmask is array lvalue</B>
|
||
scan_it(bmask); <B>bmask becomes pointer to int</B></PRE>
|
||
|
||
<P>An <B><A NAME="incomplete non-array lvalue expression">incomplete
|
||
non-array lvalue expression</A></B> designates an object that has a
|
||
<A HREF="types.html#void types" tppabs="http://ccs.ucsd.edu/c/types.html#void types"><I>void</I> type</A> or an
|
||
<A HREF="types.html#Incomplete Types" tppabs="http://ccs.ucsd.edu/c/types.html#Incomplete Types">incomplete</A> structure or union type.
|
||
You can only take the address of such an expression. For example:</P>
|
||
|
||
<PRE>
|
||
extern struct who_knows rom;
|
||
static struct who_knows *rom_base = &rom;</PRE>
|
||
|
||
<H2><A NAME="Class Conversions">Class Conversions</A></H2>
|
||
|
||
<P>Many of the expression subclasses are proper subsets of other
|
||
subclasses. In other cases, the translator can convert an expression
|
||
of one class to another when the context demands it. The following
|
||
diagram illustrates all classes and subclasses of expressions and
|
||
how they relate. Each box denotes a different class or subclass. It
|
||
contains a subset of all expressions that you can write. An unlabeled
|
||
arrow connects each subset to its containing set.</P>
|
||
|
||
<P><IMG SRC="expr_cl.gif" tppabs="http://ccs.ucsd.edu/c/gif/expr_cl.gif"></P>
|
||
|
||
<P>For example, an
|
||
<A HREF="#integer constant expression">integer constant expression</A>
|
||
is a subset of all
|
||
<A HREF="#arithmetic constant expression">arithmetic constant
|
||
expressions</A>, which in turn is a subset of all
|
||
<A HREF="#rvalue expression">rvalue expressions</A>.
|
||
An <A HREF="#incomplete non-array lvalue expression">incomplete
|
||
non-array lvalue expression</A> is not a subset of any other.
|
||
A label on an arrow tells you that a conversion
|
||
occurs if you write an expression of one class where the context requires
|
||
a result of another class. For example,
|
||
an rvalue expression that you write in a
|
||
<A HREF="#side-effects subcontext">side-effects subcontext</A>
|
||
becomes a <I>void</I> result by dropping the value
|
||
associated with the rvalue.</P>
|
||
|
||
<P>The translator can make four
|
||
<B><A NAME="context conversions">conversions</A></B>
|
||
to satisfy context:</P>
|
||
|
||
<UL>
|
||
<LI>from <A HREF="#rvalue expression">rvalue expression</A> to
|
||
<A HREF="#void expression">void</A> expression</LI>
|
||
|
||
<LI>from <A HREF="#accessible lvalue expression">accessible lvalue
|
||
expression</A> to rvalue expression</LI>
|
||
|
||
<LI>from <A HREF="#array lvalue expression">array lvalue expression</A>
|
||
to rvalue expression</LI>
|
||
|
||
<LI>from <A HREF="#function-designator expression">function-designator
|
||
expression</A> to rvalue expression</LI>
|
||
</UL>
|
||
|
||
<P>If you write an rvalue expression in a
|
||
<A HREF="#side-effects subcontext">side-effects subcontext</A>,
|
||
the translator discards the value of the expression and converts it to a
|
||
<A HREF="types.html#void types" tppabs="http://ccs.ucsd.edu/c/types.html#void types"><I>void</I> type</A>.
|
||
For example:</P>
|
||
|
||
<PRE>
|
||
int y;
|
||
y = 3; <B>rvalue y = 3 becomes void</B></PRE>
|
||
|
||
<P>If you write an
|
||
<A HREF="#accessible lvalue expression">accessible lvalue expression</A>
|
||
in an <A HREF="#rvalue subcontext">rvalue subcontext</A> (such as a
|
||
<A HREF="function.html#test context" tppabs="http://ccs.ucsd.edu/c/function.html#test context">test</A> or
|
||
<A HREF="function.html#value context" tppabs="http://ccs.ucsd.edu/c/function.html#value context">value context</A>),
|
||
the translator accesses the value stored in the object
|
||
to determine the result. A
|
||
<A HREF="types.html#Type Qualifiers" tppabs="http://ccs.ucsd.edu/c/types.html#Type Qualifiers">qualified</A> type (<I>const</I>
|
||
or <I>volatile</I>) becomes its corresponding unqualified type. For
|
||
example:</P>
|
||
|
||
<PRE>
|
||
const int x;
|
||
int y;
|
||
y = x; <B>const int lvalue x becomes int rvalue</B></PRE>
|
||
|
||
<P>If you write an
|
||
<A HREF="#array lvalue expression">array lvalue expression</A>
|
||
in an <A HREF="#rvalue subcontext">rvalue subcontext</A>,
|
||
the translator converts the type <I>array of T</I> to <I>pointer
|
||
to T.</I> The value of the expression is the address of the first element
|
||
of the array. For example:</P>
|
||
|
||
<PRE>
|
||
int a[10], *pi;
|
||
pi = a; <B>array a becomes pointer rvalue</B></PRE>
|
||
|
||
<P>If you write a
|
||
<A HREF="#function-designator expression">function-designator
|
||
expression</A> in an
|
||
<A HREF="#rvalue subcontext">rvalue subcontext</A>,
|
||
the translator converts the type <I>function returning T</I> to <I>pointer
|
||
to function returning T.</I> The value of the expression is the address
|
||
of the function. For example:</P>
|
||
|
||
<PRE>
|
||
int f(void);
|
||
int (*pf)(void);
|
||
pf = f; <B>function f becomes pointer rvalue</B></PRE>
|
||
|
||
<H2><A NAME="Type Conversions">Type Conversions</A></H2>
|
||
|
||
<P>Within several contexts the translator converts the type of
|
||
a scalar expression (or subexpression). The conversions are called:</P>
|
||
|
||
<UL>
|
||
<LI><A HREF="#Promoting">promoting</A></LI>
|
||
|
||
<LI><A HREF="#Balancing">balancing</A></LI>
|
||
|
||
<LI><A HREF="#Assigning and Type Casting">assigning</A></LI>
|
||
|
||
<LI><A HREF="#Assigning and Type Casting">type casting</A></LI>
|
||
</UL>
|
||
|
||
<P>This section describes each of these conversions and the context
|
||
in which it occurs. It also shows how the translator determines the
|
||
value of the converted type from the value of the original type.</P>
|
||
|
||
<H3><A NAME="Promoting">Promoting</A></H3>
|
||
|
||
<P>Except when it is the operand of the
|
||
<A HREF="#sizeof operator"<I>sizeof</I></A> operator, an
|
||
integer rvalue expression has one of four types:</P>
|
||
|
||
<UL>
|
||
<LI><I>int</I></LI>
|
||
|
||
<LI><I>unsigned int</I></LI>
|
||
|
||
<LI><I>long</I></LI>
|
||
|
||
<LI><I>unsigned long</I></LI>
|
||
</UL>
|
||
|
||
<P>When you write an expression in an
|
||
<A HREF="#rvalue subcontext">rvalue subcontext</A> and the expression
|
||
has an integer type that is not one of these types, the translator
|
||
<B>promotes</B> its type. If all of the values representable in the
|
||
original type are also representable as type <I>int,</I> then the
|
||
promoted type is <I>int.</I> Otherwise, the promoted type is <I>unsigned
|
||
int.</I></P>
|
||
|
||
<P>Thus, for <I>signed char, short,</I> and any <I>signed bitfield</I>
|
||
type, the promoted type is <I>int.</I> For each of the remaining integer
|
||
types (<I>char, unsigned char, unsigned short,</I> any plain <I>bitfield</I>
|
||
type, or any <I>unsigned bitfield</I> type), the effect of these rules
|
||
is to favor promoting to <I>int</I> wherever possible, but to promote
|
||
to <I>unsigned int</I> if necessary to preserve the original value
|
||
in all possible cases.</P>
|
||
|
||
<P>For example:</P>
|
||
|
||
<PRE>
|
||
signed char ch;
|
||
unsigned short us, f(char *, ...);
|
||
f("%i%x", ch, <B>ch becomes int</B>
|
||
us); <B>us becomes int or unsigned int</B></PRE>
|
||
|
||
<H3><A NAME="Balancing">Balancing</A></H3>
|
||
|
||
<P>When you write an infix operator that has two arithmetic rvalue
|
||
operands, the translator frequently determines the type of the result
|
||
by <B>balancing</B> the types of the two operands. To balance two
|
||
types, the translator applies the following rules to the promoted
|
||
types of the operands:</P>
|
||
|
||
<UL>
|
||
<LI>Unless the two types are <I>unsigned int</I> and <I>long,</I>
|
||
the balanced type is the
|
||
<A HREF="#Promoting">promoted</A> type (of the two) that occurs later
|
||
in the sequence: <I>int, unsigned int, long, unsigned long, float,
|
||
double,</I> and <I>long double.</I></LI>
|
||
|
||
<LI>If the two types are <I>unsigned int</I> and <I>long</I> and
|
||
the type <I>long</I> can represent all values of type <I>unsigned
|
||
int,</I> the balanced type is <I>long.</I></LI>
|
||
|
||
<LI>Otherwise, the balanced type is <I>unsigned long.</I></LI>
|
||
</UL>
|
||
|
||
<P>Each of the operands is converted to the balanced type, the
|
||
arithmetic operation occurs between the now identical types, and the
|
||
result of the operation has the balanced type. For example:</P>
|
||
|
||
<PRE>
|
||
int i;
|
||
long lo;
|
||
double d;
|
||
return ((i + lo) <B>i becomes long</B>
|
||
+ d); <B>(i + lo) becomes double</B></PRE>
|
||
|
||
<H3><A NAME="Assigning and Type Casting">Assigning and Type Casting</A></H3>
|
||
|
||
<P>You store a value in an object by writing an expression that
|
||
contains an <B>assigning</B> operator. The assigning operators are
|
||
<A HREF="#Assignment"><CODE>=</CODE></A>,
|
||
<A HREF="#Multiply Assign"><CODE>*=</CODE></A>,
|
||
<A HREF="#Divide Assign"><CODE>/=</CODE></A>,
|
||
<A HREF="#Remainder Assign"><CODE>%=</CODE></A>,
|
||
<A HREF="#Add Assign"><CODE>+=</CODE></A>,
|
||
<A HREF="#Subtract Assign"><CODE>-=</CODE></A>,
|
||
<A HREF="#Left Shift Assign"><CODE><<=</CODE></A>,
|
||
<A HEEF="#Right Shift Assign"><CODE>>>=</OOEE></A>,
|
||
<A HREF="#Bitwise AND Assign"><CODE>&=</CODE></A>,
|
||
<A HREF="#Bitwise Exclusive OR Assign"><CODE>^=</CODE></A>, and
|
||
<A HREF="#Bitwise Inclusive OR Assign"><CODE>|=</CODE></A>.</P>
|
||
|
||
<P>If the type of the aalue to be stored by an assigning operator is
|
||
<A HREF="types.html#Compatible and Composite Types" tppabs="http://ccs.ucsd.edu/c/types.html#Compatible and Composite Types">compatible</A>
|
||
with the type of the object, the program stores the
|
||
value unmodified. Otherwise, the translator determines the appropriate
|
||
conversion to perform before storing the new value.</P>
|
||
|
||
<P>You can also specify a type conversion by writing a
|
||
<A HREF="#Type Cast"><I>type cast</I></A> operator.
|
||
You can specify any type conversion permitted for
|
||
an assigning operator, plus several other conversions between scalar
|
||
types.</P>
|
||
|
||
<P>The translator defines a number of conversions between scalar
|
||
types that you can specify by assigning or type casting. It does not
|
||
define all possible conversions, however:</P>
|
||
|
||
<UL>
|
||
<LI>You can convert any
|
||
<A HREF="types.html#Arithmetic Types" tppabs="http://ccs.ucsd.edu/c/types.html#Arithmetic Types">arithmetic</A>
|
||
(integer or floating-point) type
|
||
to any other arithmetic type. The conversion preserves the original
|
||
value, wherever possible. Otherwise, the value changes
|
||
with the representation
|
||
as described later in this section.</LI>
|
||
|
||
<LI>You can convert any
|
||
<A HREF="types.html#Pointer Types" tppabs="http://ccs.ucsd.edu/c/types.html#Pointer Types">pointer type</A> to an
|
||
<A HREF="types.html#integer types" tppabs="http://ccs.ucsd.edu/c/types.html#integer types">integer type</A>, but the
|
||
result is always
|
||
<A HREF="portable.html#implementation defined" tppabs="http://ccs.ucsd.edu/c/portable.html#implementation defined">implementation
|
||
defined</A>.
|
||
You cannot convert a pointer type to a
|
||
<A HREF="types.html#Floating-Point Types" tppabs="http://ccs.ucsd.edu/c/types.html#Floating-Point Types">floating-point type</A>.</LI>
|
||
|
||
<LI>You can convert any integer type to any pointer type.
|
||
The value zero yields a
|
||
<A HREF="types.html#null pointer value" tppabs="http://ccs.ucsd.edu/c/types.html#null pointer value">null pointer value</A>.
|
||
Any nonzero value yields an implementation-defined
|
||
result. You cannot convert a floating-point type to a pointer type.</LI>
|
||
|
||
<LI>You can convert any object pointer or pointer to incomplete
|
||
type to any other object pointer or pointer to incomplete type. The
|
||
result is implementation defined, however, unless the original pointer
|
||
is suitably aligned for use as the resultant pointer. You can safely
|
||
convert any such pointer to a pointer to a character type (or a <I>pointer
|
||
to void</I>, which has the same repeesentation). You can use such a
|
||
pointer to character to access the first byte of the object as a character.
|
||
If you then convert that pointer to a type
|
||
<A HREF="types.html#Compatible and Composite Types" tppabs="http://ccs.ucsd.edu/c/types.html#Compatible and Composite Types">compatible</A>
|
||
with the original pointer, it will equal
|
||
the original pointer and you can use the pointer
|
||
to access the object. For example:</LI>
|
||
</UL>
|
||
|
||
<PRE>
|
||
int i;
|
||
char *pc = (char *)&i; <B>valid type cast</B>
|
||
*(int *)pc = 3; <B>also valid</B>
|
||
|
||
if (*pc == *(int *)pc) <B>also valid</B>
|
||
printf("int stores l.s. byte first\n");</PRE>
|
||
|
||
<UL>
|
||
<LI>You can convert a pointer to any
|
||
<A HREF="types.html#Function Types" tppabs="http://ccs.ucsd.edu/c/types.html#Function Types">function type</A> to a pointer
|
||
to any other function type. If you then convert that pointer to a
|
||
type compatible with the original pointer, it will equal the original
|
||
pointer and you can use the pointer to call the function. For example,
|
||
the following two type casts are both valid:</LI>
|
||
</UL>
|
||
|
||
<PRE>
|
||
extern int sum(int, int);
|
||
void (*pv)(void) = (void (*)(void))&sum;
|
||
|
||
if (((int (*)(int, int))pv)(1, 2) == 3)
|
||
printf("sum was called properly\n");</PRE>
|
||
|
||
<P>The following table summarizes all possible
|
||
scalar conversions. Note that you can convert any scalar type to any
|
||
other scalar type by specifying no more than two conversions. In many
|
||
cases, however, at least one of the conversions is
|
||
<A HREF="portable.html#implementation defined" tppabs="http://ccs.ucsd.edu/c/portable.html#implementation defined">implementation
|
||
defined</A>.</P>
|
||
|
||
<PRE>
|
||
<B>Pointer to
|
||
From: Arithmetic Incomplete Pointer to
|
||
To: Type or Object Function
|
||
|
||
Arithmetic</B> any to integer to integer
|
||
<B>Type</B> only only
|
||
|
||
<B>Pointer to</B> from integer any ---
|
||
<B>Incomplete or</B> only
|
||
<B>Object</B>
|
||
|
||
<B>Pointer to</B> from integer --- any
|
||
<B>Function</B> only</PRE>
|
||
|
||
<H3><A NAME="Changing Representations">Changing Representations</A></H3>
|
||
|
||
<P>When you convert between any two arithmetic types, what happens
|
||
to the value depends on the number of bits used to represent the original
|
||
and final types. The following table summarizes
|
||
all possible conversions between arithmetic types.
|
||
The table assumes that:</P>
|
||
|
||
<UL>
|
||
<LI>A signed integer value <CODE>X</CODE> occupying <CODE>N</CODE> bits can
|
||
represent (at least) all integers in the open-ended interval
|
||
<CODE>(-2^(N-1), 2^(N-1))</CODE>.</LI>
|
||
|
||
<LI>An unsigned integer value <CODE>X</CODE> occupying <CODE>N</CODE>
|
||
bits can represent all integers in the half-open interval
|
||
<CODE>[0, 2^N)</CODE> (and no others).</LI>
|
||
|
||
<LI>A floating-point value <CODE>X</CODE> can be characterized as having
|
||
<CODE>N</CODE> bits reserved for representing sign and magnitude, so it
|
||
can exactly represent (at least) all integers in the open-ended interval
|
||
<CODE>(-2^(N-1), 2^(N-1))</CODE>.</LI>
|
||
</UL>
|
||
|
||
<PRE>
|
||
<B>Conversion N < M N == M N > M</B>
|
||
|
||
signed integer discard m.s. same value same value
|
||
to M-N bits
|
||
signed integer (can overflow)
|
||
|
||
unsigned integer if (X < 2^(N-1)) if (X < 2^(N-1)) same value
|
||
to same value same value
|
||
signed integer else impl.-def. else impl.-def.
|
||
(can overflow) (can overflow)
|
||
|
||
floating-point if (|X| < 2^(N-1)) if (|X| < 2^(N-1)) if (|X| < 2^(N-1))
|
||
to trunc(X) trunc(X) trunc(X)
|
||
signed integer else impl.-def. else impl.-def. else impl.-def.
|
||
(can overflow) (can overflow) (can overflow)
|
||
|
||
signed integer if (0 <= X) if (0 <= X) if (0 <= X)
|
||
to X % 2^N same value same value
|
||
unsigned integer else impl.-def. else X + 2^N else X + 2^N
|
||
|
||
unsigned integer X % 2^N same value same value
|
||
to
|
||
unsigned integer
|
||
|
||
floating-point if (0 <= X < 2^N) if (0 <= X < 2^N) if (0 <= X < 2^N)
|
||
to trunc(X) trunc(X) trunc(X)
|
||
unsigned integer else impl.-def. else impl.-def. else impl.-def.
|
||
(can overflow) (can overflow) (can overflow)
|
||
|
||
signed integer keep sign, same value same value
|
||
to keep m.s.
|
||
floating-point N-1 bits
|
||
|
||
unsigned integer + sign, + sign, same value
|
||
to keep m.s. keep m.s.
|
||
floating-point N-1 bits N-1 bits
|
||
|
||
floating-point keep m.s. same value same value
|
||
to N-1 bits
|
||
floating-point (can overflow)</PRE>
|
||
|
||
<P>The table shows what happens when you convert an <CODE>M</CODE>-bit
|
||
representation with value <CODE>X</CODE>
|
||
to an <CODE>N</CODE>-bit representation,
|
||
for the three cases where <CODE>M</CODE> is less than, equal to, or greater
|
||
than <CODE>N.</CODE> The abbreviations used in this table are:</P>
|
||
|
||
<UL>
|
||
<LI><CODE>impl.-def.</CODE> --
|
||
<A HREF="portable.html#implementation defined" tppabs="http://ccs.ucsd.edu/c/portable.html#implementation defined">implementation
|
||
defined</A></LI>
|
||
|
||
<LI><CODE>m.s.</CODE> -- most significant</LI>
|
||
|
||
<LI><CODE>trunc(X)</CODE> -- the integer part of <CODE>X</CODE>,
|
||
truncated toward zero</LI>
|
||
|
||
<LI><CODE>X % Y</CODE> -- the non-negative remainder after dividing
|
||
<CODE>X</CODE> by <CODE>Y</CODE></LI>
|
||
</UL>
|
||
|
||
<H3><A NAME="Pointer Arithmetic">Pointer Arithmetic</A></H3>
|
||
|
||
<P>You can add an integer to a value of type pointer to object.
|
||
If the value of the pointer is the address of an array element, then
|
||
adding one to the value yields the address of the next array element.
|
||
Thus, for a pointer <CODE>p</CODE> to any object:</P>
|
||
|
||
<PRE>
|
||
(char *)(p + 1) <B>is identical to</B> (char *)p + sizeof (*p)</PRE>
|
||
|
||
<P>If the value of <CODE>p</CODE> is the address of the first element
|
||
in an array object, then <CODE>*(p + n)</CODE> designates element number
|
||
<CODE>n</CODE> (counting from zero).
|
||
If the value of <CODE>p</CODE> is the address
|
||
of the last element in an array object, then <CODE>(p + 1)</CODE> is a valid
|
||
address, even though <CODE>*(p + 1)</CODE> is not an accessible lvalue.
|
||
You can perform pointer arithmetic on <CODE>(p + 1)</CODE> just as you can
|
||
on the address of any of the elements of the array. If you form any
|
||
other address that does not designate an element of the array object
|
||
(by adding an integer to a pointer), the result is undefined.</P>
|
||
|
||
<H2><A NAME="Reading Expressions">Reading Expressions</A></H2>
|
||
|
||
<P>You compose an expression from one or more
|
||
<A HREF="syntax.html#term" tppabs="http://ccs.ucsd.edu/c/syntax.html#term">terms</A> and zero or more operators:</P>
|
||
|
||
<P><IMG SRC="expr.gif" tppabs="http://ccs.ucsd.edu/c/gif/expr.gif"></P>
|
||
|
||
<P>Each term has a well defined
|
||
<A HREF="types.html" tppabs="http://ccs.ucsd.edu/c/types.html">type</A> and
|
||
<A HREF="#Classes of Expressions">class</A>. If an expression
|
||
consists of a single term without operators, then the type and class
|
||
of the expression are the type and class of the term.</P>
|
||
|
||
<P>Each operator requires one, two, or three
|
||
<B><A NAME="operand">operands</A></B>. An
|
||
operand is a subexpression that can itself (generally) contain additional
|
||
operators as well as terms. If you write an expression with one or
|
||
more terms and a single operator, then the terms must be the operands
|
||
of the operator. Each operator accepts operands with only certain
|
||
combinations of types and classes. The types and classes of the operands
|
||
determine the type and class of the expression containing the operator.</P>
|
||
|
||
<P>If you write an expression with one or more terms and two operators,
|
||
then the translator must determine which terms to
|
||
<A HREF="#Grouping">group</A> with which operators.
|
||
You can enclose any subexpression in parentheses to make
|
||
clear that it groups as a single operand. Such parentheses have no
|
||
other effect than to control grouping. If you do not write such parentheses,
|
||
however, the translator applies a number of
|
||
<A HREF="#precedence">precedence</A> rules
|
||
to determine how the expression groups. Every expression you write
|
||
groups in only one way.</P>
|
||
|
||
<P>This section describes how to determine the type and class of
|
||
any term. Later sections in this documents explain the rules for grouping
|
||
operands in the presence of two or more operators, the effect of each
|
||
operator, what operands it accepts, and what result it produces.</P>
|
||
|
||
<P>A term takes one of several forms:</P>
|
||
|
||
<P><IMG SRC="term.gif" tppabs="http://ccs.ucsd.edu/c/gif/term.gif"></P>
|
||
|
||
<P>A <B><A NAME="name term">name</A></B>
|
||
in this context be declared as one of three entities:</P>
|
||
|
||
<UL>
|
||
<LI>a <A HREF="types.html#Function Types" tppabs="http://ccs.ucsd.edu/c/types.html#Function Types">function</A></LI>
|
||
|
||
<LI>an <A HREF="types.html#object types" tppabs="http://ccs.ucsd.edu/c/types.html#object types">object</A> (possibly with
|
||
<A HREF="types.html#Incomplete Types" tppabs="http://ccs.ucsd.edu/c/types.html#Incomplete Types">incomplete type</A>)</LI>
|
||
|
||
<LI>an <A HREF="types.html#enumeration constants" tppabs="http://ccs.ucsd.edu/c/types.html#enumeration constants">enumeration
|
||
constant</A></LI>
|
||
</UL>
|
||
|
||
<P>For a function, the name is a
|
||
<A HREF="#function-designator expression">function-designator expression</A>
|
||
with the declared type. For an object, the name is an
|
||
<A HREF="#lvalue expression">lvalue expression</A>
|
||
with the declared type. For an enumeration constant, the name is an
|
||
<A HREF="#rvalue expression">rvalue expression</A> with type <I>int.</I>
|
||
(You can write a
|
||
<A HREF="declare.html#Type Definition" tppabs="http://ccs.ucsd.edu/c/declare.html#Type Definition">type definition</A> or
|
||
<A HREF="declare.html#Tags" tppabs="http://ccs.ucsd.edu/c/declare.html#Tags">tag</A> in an expression only as part of a
|
||
<A HREF="declare.html#Type-Name Declaration" tppabs="http://ccs.ucsd.edu/c/declare.html#Type-Name Declaration">type-name declaration</A>
|
||
enclosed in parentheses, to make a
|
||
<A HREF="#Type Cast"><I>type cast</I></A> operator, or as the operand of a
|
||
<A HREF="#sizeof operator"><I>sizeof</I></A> operator.)</P>
|
||
|
||
<P>If no declaration is visible for one of these entities and if
|
||
you write a left parenthesis immediately following the name,
|
||
then the translator
|
||
<A HREF="function.html#implicit declaration" tppabs="http://ccs.ucsd.edu/c/function.html#implicit declaration">implicitly declares</A>
|
||
the name in the current name space
|
||
as a <I>function returning int</I> without any argument information.</P>
|
||
|
||
<P>An <A HREF="syntax.html#integer constant" tppabs="http://ccs.ucsd.edu/c/syntax.html#integer constant">integer constant</A> is an
|
||
<A HREF="#rvalue expression">rvalue expression</A> whose type
|
||
depends on the value, the base, and any suffix you write.
|
||
In all cases, the value
|
||
is the sequence of digits taken as a number to the specified base.
|
||
Each base and suffix combination determines a sequence of possible types.
|
||
The translator selects the earliest type
|
||
in the sequence that can represent the value
|
||
of the particular integer constant.</P>
|
||
|
||
<P>For a
|
||
<B><A NAME="decimal integer constant">decimal integer constant</A></B>,
|
||
the sequences are:</P>
|
||
|
||
<UL>
|
||
<LI>no suffix --<I> int, long, unsigned long</I>
|
||
|
||
<LI><CODE>U</CODE> suffix -- <I>unsigned int, unsigned long</I>
|
||
|
||
<LI><CODE>L</CODE> suffix -- <I>long, unsigned long</I>
|
||
|
||
<LI><CODE>UL</CODE> suffix -- <I>unsigned long</I></LI>
|
||
</UL>
|
||
|
||
<P>For an
|
||
<B><A NAME="octal integer constant">octal</A></B> or
|
||
<B><A NAME="hexadecimal integer constant">
|
||
hexadecimal integer constant</A></B>,
|
||
the sequences are:</P>
|
||
|
||
<UL>
|
||
<LI>no suffix --<I> int, unsigned int, long, unsigned long</I>
|
||
|
||
<LI><CODE>U</CODE> suffix -- <I>unsigned int, unsigned long</I>
|
||
|
||
<LI><CODE>L</CODE> suffix -- <I>long, unsigned long</I>
|
||
|
||
<LI><CODE>UL</CODE> suffix -- <I>unsigned long</I></LI>
|
||
</UL>
|
||
|
||
<P>For example, if type <I>int</I> has a 16-bit representation:</P>
|
||
|
||
<PRE>
|
||
70 070 0x70 <B>all type int</B>
|
||
7000U 070U 0x7000 <B>all type unsigned</B>
|
||
70000 070L 0x700L <B>all type long</B></PRE>
|
||
|
||
<P>A
|
||
<A HREF="syntax.html#floating-point constant" tppabs="http://ccs.ucsd.edu/c/syntax.html#floating-point constant">floating-point
|
||
constant</A> is an
|
||
<A HREF="#rvalue expression">rvalue expression</A> whose
|
||
type depends on any suffix you write:</P>
|
||
|
||
<UL>
|
||
<LI>no suffix -- <I>double</I>
|
||
|
||
<LI><CODE>F</CODE> suffix -- <I>float</I>
|
||
|
||
<LI><CODE>L</CODE> suffix -- <I>long double</I></LI>
|
||
</UL>
|
||
|
||
<P>Its <B><A NAME="floating-point constant">value</A></B>
|
||
is the integer plus fraction parts, taken as a decimal number,
|
||
times ten raised to the exponent part, taken as a signed decimal
|
||
number.</P>
|
||
|
||
<P>A
|
||
<A HREF="syntax.html#character constant" tppabs="http://ccs.ucsd.edu/c/syntax.html#character constant">character constant</A> is an
|
||
<A HREF="#rvalue expression">rvalue expression</A>.
|
||
If you specify just one character in
|
||
the character constant, its type depends on any prefix you write:</P>
|
||
|
||
<UL>
|
||
<LI>no prefix -- <I>int</I>
|
||
|
||
<LI><CODE>L</CODE> prefix -- the type <CODE>wchar_t</CODE>
|
||
<A HREF="#Promoting">promoted</A></LI>
|
||
</UL>
|
||
|
||
<P>Its <B><A NAME="character constant">value</A></B>
|
||
is the code for the character you specify in the
|
||
<A HREF="charset.html#target character set" tppabs="http://ccs.ucsd.edu/c/charset.html#target character set">target character set</A>.
|
||
If you specify other than one character in a character constant,
|
||
the type and value are
|
||
<A HREF="portable.html#implementation defined" tppabs="http://ccs.ucsd.edu/c/portable.html#implementation defined">implementation
|
||
defined</A>.</P>
|
||
|
||
<P>A
|
||
<B><A NAME="string literal">string literal</A></B> is an
|
||
<A HREF="#lvalue expression">lvalue expression</A> whose type depends
|
||
on the number of characters you specify and any prefix you write:</P>
|
||
|
||
<UL>
|
||
<LI>no prefix -- <I>array of char</I> with repetition count <I>N</I>
|
||
|
||
<LI><CODE>L</CODE> prefix --<I> array of</I> <CODE>wchar_t</CODE>
|
||
with repetition count <I>N</I></LI>
|
||
</UL>
|
||
|
||
<P><I>N</I> is one more than the number of characters you specify
|
||
when you write the string (for the terminating null character).
|
||
Its stored <B><A NAME="string literal">value</A></B>
|
||
is the sequence of codes for the character(s) you specify in the
|
||
target character set, followed by the value zero. For example:</P>
|
||
|
||
<PRE>
|
||
"hello" <B>type is array of 6 char</B>
|
||
L"hai" <B>type is array of 4 wchar_t</B></PRE>
|
||
|
||
<P>The term
|
||
<CODE><B><A HREF="#sizeof operator">sizeof</A></B> (<I>declaration</I>)</CODE>
|
||
is an rvalue expression of type <CODE>size_t</CODE>,
|
||
with value as described for that operator.</P>
|
||
|
||
<P>Any expression you write enclosed in
|
||
<B><A NAME="parenthesized term">parentheses</A></B> is a term whose
|
||
type, class, and value are the same as for the expression. Enclosing
|
||
an expression in parentheses has no effect other than to control grouping.</P>
|
||
|
||
<H2><A NAME="Grouping">Grouping</A></H2>
|
||
|
||
<P>In the absence of parentheses, the translator <B>groups</B>
|
||
operators with operands in the following order:</P>
|
||
|
||
<P>1. The translator applies a <B>postfix operator</B>
|
||
immediately following a term before it applies any other operator.
|
||
It then applies any postfix operators to the right of that operator,
|
||
grouping from left to right.</P>
|
||
|
||
<P><IMG SRC="postfix.gif" tppabs="http://ccs.ucsd.edu/c/gif/postfix.gif"></P>
|
||
|
||
<P>2. The translator applies a <B>prefix operator</B>
|
||
immediately preceding a term and any postfix operators.
|
||
It then applies any prefix operators to the
|
||
left of that operator, grouping from right to left.</P>
|
||
|
||
<P><IMG SRC="prefix.gif" tppabs="http://ccs.ucsd.edu/c/gif/prefix.gif"></P>
|
||
|
||
<P>3. The translator applies <B>infix operators</B>
|
||
in descending order of <A HREF="#precedence">precedence</A>.
|
||
Operators at the same order of precedence group either from left to
|
||
right or from right to left, as indicated for the particular precedence
|
||
level.</P>
|
||
|
||
<P><IMG SRC="infix.gif" tppabs="http://ccs.ucsd.edu/c/gif/infix.gif"></P>
|
||
|
||
<P>The translator resolves two ambiguities by:</P>
|
||
|
||
<UL>
|
||
<LI>always interpreting <CODE>sizeof (<I>declaration</I>)</CODE>
|
||
as a term (never as the
|
||
<A HREF="#sizeof operator"><I>sizeof</I></A> operator followed by a
|
||
<A HREF="#Type Cast"><I>type cast</I></A> operator)</LI>
|
||
|
||
<LI>always interpreting a comma within a
|
||
<A HREF="#Function Call">function call</A> argument
|
||
list as an argument expression separator (never as a
|
||
<A HREF="#Comma"><I>comma</I></A> operator
|
||
within an argument expression).</LI>
|
||
</UL>
|
||
|
||
<P>In either case, you can use parentheses to obtain the alternate
|
||
grouping.</P>
|
||
|
||
<P>The following table shows all operators grouped by
|
||
<B><A NAME="precedence">precedence</A></B> level in descending order.</P>
|
||
|
||
<PRE>
|
||
Operator Notation Grouping
|
||
|
||
postincrement X++ from left to right
|
||
postdecrement X--
|
||
subscript X[Y]
|
||
function call X(Y)
|
||
select member X.Y
|
||
point at member X->Y
|
||
|
||
sizeof sizeof X from right to left
|
||
preincrement ++X
|
||
predecrement --X
|
||
address of &X
|
||
indirection *X
|
||
plus +X
|
||
minus -X
|
||
bitwise NOT ~X
|
||
logical NOT !X
|
||
type cast (<I>declaration</I>)X
|
||
|
||
multiply X * Y from left to right
|
||
divide X / Y
|
||
remainder X % Y
|
||
|
||
add X + Y from left to right
|
||
subtract X - Y
|
||
|
||
left shift X << Y from left to right
|
||
right shift X >> Y
|
||
|
||
less than X < Y from left to right
|
||
less than or equal X <= Y
|
||
greater than X > Y
|
||
greater than or equal X >= Y
|
||
|
||
equals X == Y from left to right
|
||
not equals X != Y
|
||
|
||
bitwise AND X & Y from left to right
|
||
|
||
bitwise exclusive OR X ^ Y from left to right
|
||
|
||
bitwise inclusive OR X | Y from left to right
|
||
|
||
logical AND X && Y from left to right
|
||
|
||
logical OR X || Y from left to right
|
||
|
||
conditional Z ? X : Y from right to left
|
||
|
||
assignment X = Y from right to left
|
||
multiply assign X *= Y
|
||
divide assign X /= Y
|
||
remainder assign X %= Y
|
||
add assign X += Y
|
||
subtract assign X -= Y
|
||
left shift assign X <<= Y
|
||
right shift assign X >>= Y
|
||
bitwise AND assign X &= Y
|
||
bitwise exclusive OR assign X ^= Y
|
||
bitwise inclusive OR assign X |= Y
|
||
|
||
comma X, Y from left to right</PRE>
|
||
|
||
<P>The table also shows
|
||
how operators group within a given precedence level.</P>
|
||
|
||
<P>For example:</P>
|
||
|
||
<PRE>
|
||
y = m * x + b <B>is</B> y = ((m * x) + b)
|
||
*p++ = -x->y <B>is</B> (*(p++)) = (-(x->y))</PRE>
|
||
|
||
<H2><A NAME="Operator Summary">Operator Summary</A></H2>
|
||
|
||
<P>This section describes every operator. It lists the operators
|
||
alphabetically by name, showing how to write each one with operands
|
||
<CODE>X</CODE>, <CODE>Y</CODE>, and <CODE>Z</CODE> (as needed).
|
||
Following a description
|
||
of what the operator does is a table of all permissible combinations
|
||
of operand types and classes, with the type and class of the result
|
||
for each combination.</P>
|
||
|
||
<P>Some expressions produce a result that has an integer type that
|
||
varies among implementations. Each of these types has a type definition
|
||
that you can include in the program by including the standard header
|
||
<CODE><A HREF="stddef.html" tppabs="http://ccs.ucsd.edu/c/stddef.html"><stddef.h></A></CODE>.
|
||
The type definitions are:</P>
|
||
|
||
<UL>
|
||
<LI><CODE><A HREF="stddef.html#ptrdiff_t" tppabs="http://ccs.ucsd.edu/c/stddef.html#ptrdiff_t">ptrdiff_t</A></CODE>
|
||
(which is the type of the
|
||
<A HREF="#Subtract"><I>subtract</I></A> operator
|
||
when its operands are both pointers to objects)</LI>
|
||
|
||
<LI><CODE><A HREF="stddef.html#size_t" tppabs="http://ccs.ucsd.edu/c/stddef.html#size_t">size_t</A></CODE>
|
||
(which is the type of the
|
||
<A HREF="#sizeof operator"><I>sizeof</I></A> operator)</LI>
|
||
|
||
<LI><CODE><A HREF="stddef.html#wchar_t" tppabs="http://ccs.ucsd.edu/c/stddef.html#wchar_t">wchar_t</A></CODE>
|
||
(which is the type of an element of a
|
||
<A HREF="preproc.html#wide-character string literal" tppabs="http://ccs.ucsd.edu/c/preproc.html#wide-character string literal">wide-character
|
||
string literal</A>)</LI>
|
||
</UL>
|
||
|
||
<P>You do not have to include these type definitions in the program
|
||
to use the <I>subtract</I> or <I>sizeof</I> operators, for example,
|
||
or to write wide-character string literals.</P>
|
||
|
||
<P>If the result of an operation cannot be represented by a value
|
||
of the result type, then an
|
||
<B><A NAME="exceptional result">exceptional result</A></B> occurs:</P>
|
||
|
||
<UL>
|
||
<LI><B><A NAME="overflow">Overflow</A></B> is an exceptional result
|
||
where the value is too large to be represented by an
|
||
<A HREF="types.html#Arithmetic Types" tppabs="http://ccs.ucsd.edu/c/types.html#Arithmetic Types">arithmetic type</A>.</LI>
|
||
|
||
<LI><B><A NAME="underflow">Underflow</A></B> is an exceptional result
|
||
where the value is too small to be represented by a
|
||
<A HREF="types.html#Floating-Point Types" tppabs="http://ccs.ucsd.edu/c/types.html#Floating-Point Types">floating-point type</A>.</LI>
|
||
|
||
<LI><B><A NAME="zero divide">Zero divide</A></B> is an exceptional result
|
||
where the result of dividing by zero has no well defined value.</LI>
|
||
</UL>
|
||
|
||
<P>If any form of exceptional result occurs,
|
||
the program behavior is undefined.</P>
|
||
|
||
<P>A type described below as
|
||
<B><A NAME="Q qualified">Q qualified</A></B> is an optionally
|
||
<A HREF="types.html#Type Qualifiers" tppabs="http://ccs.ucsd.edu/c/types.html#Type Qualifiers">qualified</A> type. It can be:</P>
|
||
|
||
<UL>
|
||
<LI>unqualified</LI>
|
||
|
||
<LI><I>const</I> qualified</LI>
|
||
|
||
<LI><I>volatile</I> qualified</LI>
|
||
|
||
<LI><I>const</I> and <I>volatile</I> qualified</LI>
|
||
</UL>
|
||
|
||
<P>For pointer arithmetic, every object is considered an array
|
||
object (with perhaps only one element). If the array <CODE>a</CODE> has
|
||
<CODE>N</CODE> elements, then <CODE>a[N]</CODE>
|
||
is the element immediately beyond the array.</P>
|
||
|
||
<H2><A NAME="Add Assign">Add Assign</A></H2>
|
||
|
||
<CODE>X += Y</CODE>
|
||
|
||
<P>You write <CODE>X += Y</CODE> to access the value stored in the object
|
||
designated by <CODE>X</CODE>, add the value of <CODE>Y</CODE>
|
||
to the stored value, and store the new value back in the object.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of X arithmetic arithmetic
|
||
rvalue modifiable lvalue rvalue
|
||
|
||
type of X pointer to object integer
|
||
rvalue modifiable lvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Add">Add</A></H2>
|
||
|
||
<CODE>X + Y</CODE>
|
||
|
||
<P>You write <CODE>X + Y</CODE> to add the value of
|
||
<CODE>Y</CODE> to the value of <CODE>X</CODE>.
|
||
You can add an integer to a pointer value only if the
|
||
result is the address of an element within (or just beyond) the same
|
||
array object.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
balanced type of X and Y arithmetic arithmetic
|
||
rvalue rvalue rvalue
|
||
|
||
type of X pointer to object integer
|
||
rvalue rvalue rvalue
|
||
|
||
type of Y integer pointer to object
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Address of">Address of</A></H2>
|
||
|
||
<CODE>&X</CODE>
|
||
|
||
<P>You write <CODE>&X</CODE> to obtain the address of the function or
|
||
object designated by <CODE>X</CODE>. You cannot obtain the address of an
|
||
object declared with storage class <CODE>register</CODE>.</P>
|
||
|
||
<PRE><B>
|
||
Result X</B>
|
||
pointer to T any object type T
|
||
rvalue except bitfield
|
||
lvalue
|
||
|
||
pointer to T incomplete type T
|
||
rvalue lvalue
|
||
|
||
pointer to T function type T
|
||
rvalue function designator</PRE>
|
||
|
||
<H2><A NAME="Assignment">Assignment</A></H2>
|
||
|
||
<CODE>X = Y</CODE>
|
||
|
||
<P>You write <CODE>X = Y</CODE> to store
|
||
the value of <CODE>Y</CODE> in the object
|
||
designated by <CODE>X</CODE>. If <CODE>Y</CODE>
|
||
is an lvalue expression (that is converted to
|
||
an rvalue expression to obtain its stored value),
|
||
then the object it designates either must have no bytes in common
|
||
with the object designated by <CODE>X</CODE> or must overlap exactly, and
|
||
the objects must have compatible types.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of X arithmetic arithmetic
|
||
rvalue modifiable lvalue rvalue
|
||
|
||
type of X pointer, structure, or type of X
|
||
rvalue union type T rvalue
|
||
modifiable lvalue
|
||
|
||
type of X pointer to qualified T pointer to same or
|
||
rvalue modifiable lvalue less qualified type
|
||
compatible with T
|
||
rvalue
|
||
|
||
type of X pointer to void pointer to object
|
||
rvalue modifiable lvalue or incomplete type
|
||
rvalue
|
||
|
||
type of X pointer to object pointer to void
|
||
rvalue or incomplete type rvalue
|
||
modifiable lvalue
|
||
|
||
type of X any pointer type integer zero
|
||
rvalue modifiable lvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Bitwise AND Assign">Bitwise AND Assign</A></H2>
|
||
|
||
<CODE>X &= Y</CODE>
|
||
|
||
<P>You write <CODE>X &= Y</CODE> to access
|
||
the value stored in the object
|
||
designated by <CODE>X</CODE>, form the
|
||
<A HREF="#Bitwise AND">bitwise AND</A> of the value
|
||
of <CODE>Y</CODE> with the stored value,
|
||
and store the new value back in the object.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of X integer integer
|
||
rvalue modifiable lvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Bitwise AND">Bitwise AND</A></H2>
|
||
|
||
<CODE>X & Y</CODE>
|
||
|
||
<P>You write <CODE>X & Y</CODE> to form
|
||
the bitwise AND of the values of
|
||
<CODE>X</CODE> and <CODE>Y</CODE>. Each bit of the result
|
||
is set if the corresponding
|
||
bits in both <CODE>X</CODE> and <CODE>Y</CODE> are set.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
balanced type of X and Y integer integer
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Bitwise Exclusive OR Assign">Bitwise Exclusive OR Assign</A></H2>
|
||
|
||
<CODE>X ^= Y</CODE>
|
||
|
||
<P>You write <CODE>X ^= Y</CODE> to access the value stored in the object
|
||
designated by <CODE>X</CODE>, form the
|
||
<A HREF="#Bitwise Exclusive OR">bitwise exclusive OR</A> of the value
|
||
of <CODE>Y</CODE> with the stored value, and store the new value back in
|
||
the object.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of X integer integer
|
||
rvalue modifiable lvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Bitwise Exclusive OR">Bitwise Exclusive OR</A></H2>
|
||
|
||
<CODE>X ^ Y</CODE>
|
||
|
||
<P>You write <CODE>X ^ Y</CODE> to form the bitwise exclusive OR of the
|
||
values of <CODE>X</CODE> and <CODE>Y</CODE>. Each bit of the result is set if
|
||
the corresponding bits in <CODE>X</CODE> and <CODE>Y</CODE> differ.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
balanced type of X and Y integer integer
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Bitwise Inclusive OR Assign">Bitwise Inclusive OR Assign</A></H2>
|
||
|
||
<CODE>X |= Y</CODE>
|
||
|
||
<P>You write <CODE>X |= Y</CODE> to access the value stored in the object
|
||
designated by <CODE>X</CODE>, form the
|
||
<A HREF="#Bitwise Inclusive OR">bitwise inclusive OR</A> of the value
|
||
of <CODE>Y</CODE> with the stored value, and store the new value back in
|
||
the object.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of X integer integer
|
||
rvalue modifiable lvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Bitwise Inclusive OR">Bitwise Inclusive OR</A></H2>
|
||
|
||
<CODE>X | Y</CODE>
|
||
|
||
<P>You write <CODE>X | Y</CODE> to form the bitwise inclusive OR of the
|
||
values of <CODE>X</CODE> and <CODE>Y</CODE>. Each bit of the result is set if
|
||
either of the corresponding bits in
|
||
<CODE>X</CODE> or <CODE>Y</CODE> is set.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
balanced type of X and Y integer integer
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Bitwise NOT">Bitwise NOT</A></H2>
|
||
|
||
<CODE>~X</CODE>
|
||
|
||
<P>You write <CODE>~X</CODE> to form the bitwise NOT of the value of
|
||
<CODE>X</CODE>. Each bit of the result is set if the corresponding bit in
|
||
<CODE>X</CODE> is not set.</P>
|
||
|
||
<PRE><B>
|
||
Result X</B>
|
||
type of X integer
|
||
rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Comma">Comma</A></H2>
|
||
|
||
<CODE>X, Y</CODE>
|
||
|
||
<P>You write <CODE>X, Y</CODE> to first evaluate <CODE>X</CODE> as a
|
||
<A HREF="function.html#side-effects context" tppabs="http://ccs.ucsd.edu/c/function.html#side-effects context">side-effects context</A>
|
||
expression and then to evaluate <CODE>Y</CODE>. There is a
|
||
<A HREF="#sequence point">sequence point</A>
|
||
between the evaluation of the two operands.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of Y void expression any
|
||
rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Conditional">Conditional</A></H2>
|
||
|
||
<CODE>Z ? X : Y</CODE>
|
||
|
||
<P>You write <CODE>Z ? X : Y</CODE> to evaluate
|
||
one of the operands <CODE>X</CODE> or <CODE>Y</CODE>,
|
||
depending on the value of the
|
||
<A HREF="function.html#test context" tppabs="http://ccs.ucsd.edu/c/function.html#test context">test-context</A> expression
|
||
<CODE>Z</CODE>, which must be a scalar rvalue.
|
||
If <CODE>Z</CODE> has a nonzero value,
|
||
then only <CODE>X</CODE> is evaluated; otherwise, only <CODE>Y</CODE> is
|
||
evaluated. The value of the expression is the value of the operand
|
||
that is evaluated, converted to the result type. A
|
||
<A HREF="#sequence point">sequence point</A>
|
||
occurs between the evaluation of <CODE>Z</CODE>
|
||
and the evaluation of <CODE>X</CODE> or <CODE>Y</CODE>.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
balanced type of X and Y arithmetic arithmetic
|
||
rvalue rvalue rvalue
|
||
|
||
type of X structure or union type of X
|
||
rvalue rvalue rvalue
|
||
|
||
type of X pointer to T integer zero
|
||
rvalue rvalue rvalue
|
||
|
||
type of Y integer zero pointer to T
|
||
rvalue rvalue rvalue
|
||
|
||
pointer to pointer to pointer to
|
||
Q and Q' qualified Q qualified Q' qualified
|
||
composite of T and T' type T compatible type T'
|
||
rvalue rvalue rvalue
|
||
|
||
pointer to pointer to pointer to
|
||
Q and Q' qualified Q qualified Q' qualified
|
||
void void object or
|
||
rvalue rvalue incomplete type
|
||
rvalue
|
||
|
||
pointer to pointer to pointer to
|
||
Q and Q' qualified Q qualified Q' qualified
|
||
void object or void
|
||
rvalue incomplete type rvalue
|
||
rvalue
|
||
|
||
void expression void expression void expression</PRE>
|
||
|
||
<H2><A NAME="Divide Assign">Divide Assign</A></H2>
|
||
|
||
<CODE>X /= Y</CODE>
|
||
|
||
<P>You write <CODE>X /= Y</CODE> to access the value stored in the object
|
||
designated by <CODE>X</CODE>, divide that value by the value of <CODE>Y</CODE>,
|
||
and store the new value back in the object. (See the <I>Divide</I>
|
||
operator following.)</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of X arithmetic arithmetic
|
||
rvalue modifiable lvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Divide">Divide</A></H2>
|
||
|
||
<CODE>X / Y</CODE>
|
||
|
||
<P>You write <CODE>X / Y</CODE> to divide the value of <CODE>X</CODE> by the
|
||
value of <CODE>Y</CODE>. Dividing by by zero yields an
|
||
<A HREF="#exceptional result">exceptional result</A>.
|
||
For integer types, a positive quotient truncates toward zero.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
balanced type of X and Y arithmetic arithmetic
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Equals">Equals</A></H2>
|
||
|
||
<CODE>X == Y</CODE>
|
||
|
||
<P>You write <CODE>X == Y</CODE> to test whether the value of <CODE>X</CODE>
|
||
equals the value of <CODE>Y</CODE>. The result is an <I>int</I> rvalue whose
|
||
value is 1 if the test is successful; otherwise, the value is zero.
|
||
Eachoof the operands is converted to a common test type for the comparison.
|
||
The table below shows the test type, rather than the result type. </P>
|
||
|
||
<PRE><B>
|
||
Test X Y</B>
|
||
balanced type of X and Y arithmetic arithmetic
|
||
rvalue rvalue rvalue
|
||
|
||
type of X pointer to T integer zero
|
||
rvalue rvalue rvalue
|
||
|
||
type of Y integer zero pointer to T
|
||
rvalue rvalue rvalue
|
||
|
||
pointer to pointer to pointer to
|
||
Q and Q' qualified Q qualified Q' qualified
|
||
composite of T and T' type T compatible type T'
|
||
rvalue rvalue rvalue
|
||
|
||
pointer to pointer to pointer to
|
||
Q and Q' qualified Q qualified Q' qualified
|
||
void void object or
|
||
rvalue rvalue incomplete type
|
||
rvalue
|
||
|
||
pointer to pointer to pointer to
|
||
Q and Q' qualified Q qualified Q' qualified
|
||
void object or void
|
||
rvalue incomplete type rvalue
|
||
rvalue</PRE>
|
||
|
||
<H2><A NAME="Function Call">Function Call</A></H2>
|
||
|
||
<CODE>X(Y)</CODE>
|
||
|
||
<P>You write <CODE>X(Y)</CODE> to call a function.
|
||
The value of the expression
|
||
(if any) is the value that the function returns. A
|
||
<A HREF="#sequence point">sequence point</A>
|
||
occurs after the program evaluates <CODE>X</CODE>
|
||
and <CODE>Y</CODE> and before it
|
||
<A HREF="function.html#Function Calls" tppabs="http://ccs.ucsd.edu/c/function.html#Function Calls">calls</A> the function.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
object type T function returning T zero or more
|
||
rvalue function designator argument rvalues
|
||
|
||
object type T pointer to function zero or more
|
||
rvalue returning T argument rvalues
|
||
rvalue
|
||
|
||
void expression function returnigg zero or more
|
||
void argument rvalues
|
||
function designator
|
||
void expression pointer to function zerooor more
|
||
returning void argument rvalues
|
||
rvalue</PRE>
|
||
|
||
<H2><A NAME="Greater Than Or Equal">Greater Than Or Equal</A></H2>
|
||
|
||
<CODE>X >= Y</CODE>
|
||
|
||
<P>You write <CODE>X >= Y</CODE> to test
|
||
whether the value of <CODE>X</CODE>
|
||
is greater than or equal to the value of <CODE>Y</CODE>. The result is an
|
||
<I>int</I> rvalue whose value is 1 if the test is successful; otherwise,
|
||
the value is zero. Each of the operands is converted to a common test
|
||
type for the comparison. You can compare two pointer values only if
|
||
they are the addresses of elements within (or just beyond) the same
|
||
array object. The table below shows the test type, rather than the
|
||
result type.</P>
|
||
|
||
<PRE><B>
|
||
Test X Y</B>
|
||
balanced type of X and Y arithmetic arithmetic
|
||
rvalue rvalue rvalue
|
||
|
||
pointer to pointer to pointer to
|
||
Q and Q' qualified Q qualified Q' qualified
|
||
composite of T and T' type T compatible type T'
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Greater Than">Greater Than</A></H2>
|
||
|
||
<CODE>X > Y</CODE>
|
||
|
||
<P>You write <CODE>X > Y</CODE> to test
|
||
whether the value of <CODE>X</CODE> is
|
||
greater than the value of <CODE>Y</CODE>. The result is an <I>int</I> rvalue
|
||
whose value is 1 if the test is successful; otherwise, the value is
|
||
zero. Each of the operands is converted to a common test type for
|
||
the comparison. You can compare two pointer values only if they are
|
||
the addresses of elements within (or just beyond) the same array object.
|
||
The table below shows the test type, rather than the result type. </P>
|
||
|
||
<PRE><B>
|
||
Test X Y</B>
|
||
balanced type of X and Y arithmetic arithmetic
|
||
rvalue rvalue rvalue
|
||
|
||
pointer to pointer to pointer to
|
||
Q and Q' qualified Q qualified Q' qualified
|
||
composite of T and T' type T compatible type T'
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Indirection">Indirection</A></H2>
|
||
|
||
<CODE>*X</CODE>
|
||
|
||
<P>You write <CODE>*X</CODE> to use the value of the pointer <CODE>X</CODE>
|
||
to designate an entity. The address of the entity is the value of
|
||
the pointer.</P>
|
||
|
||
<PRE><B>
|
||
Result X</B>
|
||
type T pointer to object type T
|
||
lvalue rvalue
|
||
|
||
type T pointer to function type T
|
||
function designator rvalue
|
||
|
||
void expression pointer to void
|
||
rvalue</PRE>
|
||
|
||
<H2><A NAME="Left Shift Assign">Left Shift Assign</A></H2>
|
||
|
||
<CODE>X <<= Y</CODE>
|
||
|
||
<P>You write <CODE>X <<= Y</CODE>
|
||
to access the value stored in the object
|
||
designated by <CODE>X</CODE>,
|
||
<A HREF="#Left Shift">shift</A> that value to the left by the number
|
||
of bit positions specified by the value of <CODE>Y</CODE>, and store the
|
||
new value back in the object.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of X integer integer
|
||
rvalue modifiable lvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Left Shift">Left Shift</A></H2>
|
||
|
||
<CODE>X << Y</CODE>
|
||
|
||
<P>You write <CODE>X << Y</CODE>
|
||
to shift the value of <CODE>X</CODE> to the
|
||
left by the number of bit positions
|
||
specified by the value of <CODE>Y</CODE>.
|
||
For an <CODE>N</CODE>-bit representation for the
|
||
<A HREF="#Promoting">promoted</A> value of <CODE>X</CODE>,
|
||
the value of <CODE>Y</CODE> must be in the interval
|
||
<CODE>[0, N)</CODE>. Zeros
|
||
fill the vacated bit positions.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of X integer integer
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Less Than Or Equal">Less Than Or Equal</A></H2>
|
||
|
||
<CODE>X <= Y</CODE>
|
||
|
||
<P>You write <CODE>X <= Y</CODE>
|
||
to test whether the value of <CODE>X</CODE>
|
||
is less than or equal to the value of <CODE>Y</CODE>.
|
||
The result is an <I>int</I>
|
||
rvalue whose value is 1 if the test is successful; otherwise, the
|
||
value is zero. Each of the operands is converted to a common test
|
||
type for the comparison. You can compare two pointer values only if
|
||
they are the addresses of elements within (or just beyond) the same
|
||
array object. The table below shows the test type, rather than the
|
||
result type.</P>
|
||
|
||
<PRE><B>
|
||
Test X Y</B>
|
||
balanced type of X and Y arithmetic arithmetic
|
||
rvalue rvalue rvalue
|
||
|
||
pointer to pointer to pointer to
|
||
Q and Q' qualified Q qualified Q' qualified
|
||
composite of T and T' type T compatible type T'
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Less Than">Less Than</A></H2>
|
||
|
||
<CODE>X < Y</CODE>
|
||
|
||
<P>You write <CODE>X < Y</CODE> to test
|
||
whether the value of <CODE>X</CODE> is
|
||
less than the value of <CODE>Y</CODE>. The result is an <I>int</I> rvalue
|
||
whose value is 1 if the test is successful; otherwise, the value is
|
||
zero. Each of the operands is converted to a common test type for
|
||
the comparison. You can compare two pointer values only if they are
|
||
the addresses of elements within (or just beyond) the same array object.
|
||
The table below shows the test type, rather than the result type.</P>
|
||
|
||
<PRE><B>
|
||
Test X Y</B>
|
||
balanced type of X and Y arithmetic arithmetic
|
||
rvalue rvalue rvalue
|
||
|
||
pointer to pointer to pointer to
|
||
Q and Q' qualified Q qualified Q' qualified
|
||
composite of T and T' type T compatible type T'
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Logical AND">Logical AND</A></H2>
|
||
|
||
<CODE>X && Y</CODE>
|
||
|
||
<P>You write <CODE>X && Y</CODE>
|
||
to test whether both of the operands <CODE>X</CODE>
|
||
and <CODE>Y</CODE> are nonzero. If <CODE>X</CODE> is zero,
|
||
then only <CODE>X</CODE> is evaluated and the value
|
||
of the expression is zero; otherwise, <CODE>Y</CODE>
|
||
is evaluated and the value of the expression is 1
|
||
if <CODE>Y</CODE> is nonzero or zero if <CODE>Y</CODE> is zero.
|
||
A <A HREF="#sequence point">sequence point</A> occurs between the evaluation
|
||
of <CODE>X</CODE> and the evaluation of <CODE>Y</CODE>.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
int scalar scalar
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Logical NOT">Logical NOT</A></H2>
|
||
|
||
<CODE>!X</CODE>
|
||
|
||
<P>You write <CODE>!X</CODE> to test
|
||
whether <CODE>X</CODE> is zero. If <CODE>X</CODE>
|
||
is zero, the value of the expression is 1; otherwise, the value is
|
||
zero.</P>
|
||
|
||
<PRE><B>
|
||
Result X</B>
|
||
int scalar
|
||
rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Logical OR">Logical OR</A></H2>
|
||
|
||
<CODE>X || Y</CODE>
|
||
|
||
<P>You write <CODE>X || Y</CODE> to test whether either of the operands
|
||
<CODE>X</CODE> or <CODE>Y</CODE> is nonzero.
|
||
If <CODE>X</CODE> has a nonzero value,
|
||
then only <CODE>X</CODE> is evaluated and the value of the expression is
|
||
1; otherwise, <CODE>Y</CODE> is evaluated and the value of the expression
|
||
is 1 if <CODE>Y</CODE> is nonzero or zero if <CODE>Y</CODE> is zero. A
|
||
<A HREF="#sequence point">sequence point</A>
|
||
occurs between the evaluation of <CODE>X</CODE> and the evaluation
|
||
of <CODE>Y</CODE>.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
int scalar scalar
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Minus"></A></H2>
|
||
|
||
<CODE>-X</CODE>
|
||
|
||
<P>You write <CODE>-X</CODE> to negate the value of <CODE>X</CODE>.</P>
|
||
|
||
<PRE><B>
|
||
Result X</B>
|
||
type of X arithmetic
|
||
rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Multiply Assign">Multiply Assign</A></H2>
|
||
|
||
<CODE>X *= Y</CODE>
|
||
|
||
<P>You write <CODE>X *= Y</CODE> to access the value stored in the object
|
||
designated by <CODE>X</CODE>, multiply
|
||
that value by the value of <CODE>Y</CODE>,
|
||
and store the new value back in the object.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of X arithmetic arithmetic
|
||
rvalue modifiable lvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Multiply">Multiply</A></H2>
|
||
|
||
<P>You write <CODE>X * Y</CODE> to multiply
|
||
the value of <CODE>X</CODE> by the
|
||
value of <CODE>Y</CODE>.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
balanced type of X and Y arithmetic arithmetic
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Not Equals">Not Equals</A></H2>
|
||
|
||
<CODE>X != Y</CODE>
|
||
|
||
<P>You write <CODE>X != Y</CODE> to test whether the value of <CODE>X</CODE>
|
||
does not equal the value of <CODE>Y</CODE>. The result is an <I>int</I>
|
||
rvalue whose value is 1 if the test is successful; otherwise, the
|
||
value is zero. Each of the operands is converted to a common test
|
||
type for the comparison. The table below shows the test type, rather
|
||
than the result type.</P>
|
||
|
||
<PRE><B>
|
||
Test X Y</B>
|
||
balanced type of X and Y arithmetic arithmetic
|
||
rvalue rvalue rvalue
|
||
|
||
type of X pointer to T integer zero
|
||
rvalue rvalue rvalue
|
||
|
||
type of Y integer zero pointer to T
|
||
rvalue rvalue rvalue
|
||
|
||
pointer to pointer to pointer to
|
||
Q and Q' qualified Q qualified Q' qualified
|
||
composite of T and T' type T compatible type T'
|
||
rvalue rvalue rvalue
|
||
|
||
pointer to pointer to pointer to
|
||
Q and Q' qualified Q qualified Q' qualified
|
||
void void object or
|
||
rvalue rvalue incomplete type
|
||
rvalue
|
||
|
||
pointer to pointer to pointer to
|
||
Q and Q' qualified Q qualified Q' qualified
|
||
void object or void
|
||
rvalue incomplete type rvalue
|
||
rvalue</PRE>
|
||
|
||
<H2><A NAME="Plus">Plus</A></H2>
|
||
|
||
<CODE>+X</CODE>
|
||
|
||
<P>You write <CODE>+X</CODE> to leave
|
||
the value of <CODE>X</CODE> unchanged.
|
||
(You use this operator primarily to emphasize
|
||
that a term is not negated.)</P>
|
||
|
||
<PRE><B>
|
||
Result X</B>
|
||
type of X arithmetic
|
||
rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Point at">Point at</A></H2>
|
||
|
||
<CODE>X->Y</CODE>
|
||
|
||
<P>You write <CODE>X->Y</CODE> to select
|
||
the member whose name is <CODE>Y</CODE>
|
||
from the structure or union whose address
|
||
is the value of <CODE>X</CODE>.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of member Y pointer to member name within
|
||
lvalue structure or union structure or union
|
||
rvalue</PRE>
|
||
|
||
<H2><A NAME="Postdecrement">Postdecrement</A></H2>
|
||
|
||
<CODE>X--</CODE>
|
||
|
||
<P>You write <CODE>X--</CODE> to access the value stored in the object
|
||
designated by <CODE>X</CODE>, subtract 1 from the value, and store the new
|
||
value back in the object. The value of the expression is the <I>original</I>
|
||
value stored in the object.</P>
|
||
|
||
<PRE><B>
|
||
Result X</B>
|
||
type T scalar type T
|
||
rvalue modifiable lvalue</PRE>
|
||
|
||
<H2><A NAME="Postincrement">Postincrement</A></H2>
|
||
|
||
<CODE>X++</CODE>
|
||
|
||
<P>You write <CODE>X++</CODE> to access the value stored in the object
|
||
designated by <CODE>X</CODE>, add 1 to the value, and store the new value
|
||
back in the object. The value of the expression is the <I>original</I>
|
||
value stored in the object.</P>
|
||
|
||
<PRE><B>
|
||
Result X</B>
|
||
type T scalar type T
|
||
rvalue modifiable lvalue</PRE>
|
||
|
||
<H2><A NAME="Predecrement">Predecrement</A></H2>
|
||
|
||
<CODE>--X</CODE>
|
||
|
||
<P>You write <CODE>--X</CODE> to access the value stored in the object
|
||
designated by <CODE>X</CODE>, subtract 1 from the value, and store the new
|
||
value back in the object. The value of the expression is the <I>final</I>
|
||
value stored in the object.</P>
|
||
|
||
<PRE><B>
|
||
Result X</B>
|
||
type T scalar type T
|
||
rvalue modifiable lvalue</PRE>
|
||
|
||
<H2><A NAME="Preincrement">Preincrement</A></H2>
|
||
|
||
<CODE>++X</CODE>
|
||
|
||
<P>You write <CODE>++X</CODE> to access the value stored in the object
|
||
designated by <CODE>X</CODE>, add 1 to the value, and store the new value
|
||
back in the object. The value of the expression is the <I>final</I>
|
||
value stored in the object.</P>
|
||
|
||
<PRE><B>
|
||
Result X</B>
|
||
type T scalar type T
|
||
rvalue modifiable lvalue</PRE>
|
||
|
||
<H2><A NAME="Remainder Assign">Remainder Assign</A></H2>
|
||
|
||
<CODE>X %= Y</CODE>
|
||
|
||
<P>You write <CODE>X %= Y</CODE> to access the value stored in the object
|
||
designated by <CODE>X</CODE>, divide
|
||
that value by the value of <CODE>Y</CODE>, and store the
|
||
<A HREF="#Remainder">remainder</A> back in the object.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of X integer integer
|
||
rvalue modifiable lvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Remainder">Remainder</A></H2>
|
||
|
||
<CODE>X % Y</CODE>
|
||
|
||
<P>You write <CODE>X % Y</CODE> to compute the remainder of the value of
|
||
<CODE>X</CODE> divided by the value of <CODE>Y</CODE>.
|
||
Dividing by by zero yields an
|
||
<A HREF="#exceptional result">exceptional result</A>.
|
||
Barring overflow or division by zero, it is always true that
|
||
<CODE>X = (X / Y) * Y + (X % Y)</CODE>.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
balanced type of X and Y integer integer
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Right Shift Assign">Right Shift Assign</A></H2>
|
||
|
||
<CODE>X >>= Y</CODE>
|
||
|
||
<P>You write <CODE>X >>= Y</CODE> to access
|
||
the value stored in the object designated by <CODE>X</CODE>,
|
||
<A HREF="#Right Shift">shift</A> that value to the right by the number
|
||
of bit positions specified by the value of <CODE>Y</CODE>, and store the
|
||
new value back in the object.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of X integer integer
|
||
rvalue modifiable lvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Right Shift">Right Shift</A></H2>
|
||
|
||
<CODE>X >> Y</CODE>
|
||
|
||
<P>You write <CODE>X >> Y</CODE>
|
||
to shift the value of <CODE>X</CODE> to the
|
||
right by the number of bit positions
|
||
specified by the value of <CODE>Y</CODE>.
|
||
For an <CODE>N</CODE>-bit representation
|
||
for the value of <CODE>X</CODE>, the
|
||
(promoted) value of <CODE>Y</CODE> must be in the interval
|
||
<CODE>[0, N)</CODE>.
|
||
If <CODE>X</CODE> is nonnegative, then zeros fill the vacated bit positions;
|
||
otherwise, the result is
|
||
<A HREF="portable.html#implementation defined" tppabs="http://ccs.ucsd.edu/c/portable.html#implementation defined">implementation
|
||
defined</A>.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
balanced type of X and Y integer integer
|
||
rvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Select">Select</A></H2>
|
||
|
||
<CODE>X.Y</CODE>
|
||
|
||
<P>You write <CODE>X.Y</CODE> to select the member <CODE>Y</CODE> from the
|
||
structure or union <CODE>X</CODE>. The result is an lvalue expression only
|
||
if <CODE>X</CODE> is an lvalue expression.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of member Y structure or union member name within
|
||
lvalue lvalue the structure or union
|
||
|
||
type of member Y structure or union member name within
|
||
rvalue rvalue the structure or union</PRE>
|
||
|
||
<H2><A NAME="sizeof operator">sizeof</A></H2>
|
||
|
||
<CODE>sizeof X</CODE>
|
||
|
||
<P>You write <CODE>sizeof X</CODE> to determine the size in bytes of
|
||
an object whose type is the type of <CODE>X</CODE>.
|
||
Do not write a function-designator expression for <CODE>X</CODE>.
|
||
The translator uses the expression you write
|
||
for <CODE>X</CODE> only to determine a type;
|
||
it is not evaluated. The operand <CODE>X</CODE>
|
||
is otherwise not considered a part of the expression containing
|
||
the <I>sizeof</I> operator. Therefore, prohibitions on what can be
|
||
in an expression (such as an arithmetic constant expression) do not
|
||
apply to any part of <CODE>X</CODE>.</P>
|
||
|
||
<PRE><B>
|
||
Result X</B>
|
||
size_t object type
|
||
rvalue lvalue
|
||
|
||
size_t object type
|
||
rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Subscript">Subscript</A></H2>
|
||
|
||
<CODE>X[Y]</CODE>
|
||
|
||
<P>You write <CODE>X[Y]</CODE> to designate an array element. The operator
|
||
is identical in effect to <CODE>*((X)+(Y))</CODE>.
|
||
Typically, <CODE>X</CODE> is
|
||
an array lvalue expression (which becomes a pointer rvalue expression)
|
||
or an rvalue expression of some pointer type whose value is the address
|
||
of an array element. In this case, <CODE>Y</CODE> is an integer rvalue.
|
||
The designated array element is <CODE>Y</CODE> elements away from the element
|
||
designated by <CODE>X</CODE>. Because of the symmetry of the two operands,
|
||
however, you can write them in either order.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
object type T pointer to T integer
|
||
lvalue rvalue rvalue
|
||
|
||
object type T integer pointer to T
|
||
lvalue rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Subtract Assign">Subtract Assign</A></H2>
|
||
|
||
<CODE>X -= Y</CODE>
|
||
|
||
<P>You write <CODE>X -= Y</CODE> to access the value stored in the object
|
||
designated by <CODE>X</CODE>,
|
||
<A HREF="#Subtract">subtract</A> the value of <CODE>Y</CODE> from the value,
|
||
and store the new value back in the object.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
type of X arithmetic arithmetic
|
||
rvalue modifiable lvalue rvalue
|
||
|
||
type of X pointer to object integer
|
||
rvalue modifiable lvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Subtract">Subtract</A></H2>
|
||
|
||
<CODE>X - Y</CODE>
|
||
|
||
<P>You write <CODE>X - Y</CODE> to subtract the value of <CODE>Y</CODE> from
|
||
the value of <CODE>X</CODE>. You can subtract two pointer values only if
|
||
they are the addresses of elements within (or just beyond) the same
|
||
array object. The result tells you how many elements lie between the
|
||
two addresses.</P>
|
||
|
||
<PRE><B>
|
||
Result X Y</B>
|
||
balanced type of X and Y arithmetic arithmetic
|
||
rvalue rvalue rvalue
|
||
|
||
type of X pointer to object integer
|
||
rvalue rvalue rvalue
|
||
|
||
ptrdiff_t pointer to Q qualified pointer to Q' qualified
|
||
rvalue object type T compatible type T'
|
||
rvalue rvalue</PRE>
|
||
|
||
<H2><A NAME="Type Cast">Type Cast</A></H2>
|
||
|
||
<CODE>(<I>decl</I>)X</CODE>
|
||
|
||
<P>You write <CODE>(<I>decl</I>)X</CODE> to
|
||
<A HREF="#Type Conversions">convert</A> the value of <CODE>X</CODE>
|
||
to the scalar (or <I>void</I>) type <I>T</I> that you specify in the
|
||
type-name declaration <CODE><I>decl</I></CODE>
|
||
enclosed in parentheses. The table
|
||
below shows valid combinations of declared type and operand type.</P>
|
||
|
||
<PRE><B>
|
||
Result Type T X</B>
|
||
type T integer scalar
|
||
rvalue rvalue
|
||
|
||
type T floating-point arithmetic
|
||
rvalue rvalue
|
||
|
||
type T pointer to integer
|
||
rvalue any type rvalue
|
||
|
||
type T pointer to object pointer to object
|
||
rvalue or incomplete type or incomplete type
|
||
rvalue
|
||
|
||
type T pointer to pointer to
|
||
rvalue function function
|
||
rvalue
|
||
|
||
void expression void scalar rvalue or
|
||
void expression</PRE>
|
||
|
||
<H2><A NAME="Order of Evaluation">Order of Evaluation</A></H2>
|
||
|
||
<P>When the program evaluates an expression, it has considerable
|
||
latitude in choosing the <B>order</B> in which it evaluates subexpressions.
|
||
For example, the translator can alter:</P>
|
||
|
||
<PRE>
|
||
y = *p++;</PRE>
|
||
|
||
<P>either to:</P>
|
||
|
||
<PRE>
|
||
temp = p; p += 1; y = *temp;</PRE>
|
||
|
||
<P>or to:</P>
|
||
|
||
<PRE>
|
||
y = *p; p += 1;</PRE>
|
||
|
||
<P>As another example, the program can evaluate the expression</P>
|
||
|
||
<PRE>
|
||
f() + g()</PRE>
|
||
|
||
<P>by calling the functions in either order.</P>
|
||
|
||
<P>The order of evaluation is important in understanding when
|
||
<A HREF="function.html#side effects" tppabs="http://ccs.ucsd.edu/c/function.html#side effects">side effects</A> occur,
|
||
such as storing a value in an object.</P>
|
||
|
||
<P>A <B><A NAME="sequence point">sequence point</A></B>
|
||
is a point in the program at which you
|
||
can determine which side effects have occurred and which have yet
|
||
to take place. Each of the expressions you write as part of a statement,
|
||
for example, has a sequence point at the end of it. You can be sure
|
||
that for:</P>
|
||
|
||
<PRE>
|
||
y = 37;
|
||
x += y;</PRE>
|
||
|
||
<P>the program stores the value 37 in <CODE>y</CODE> before it accesses
|
||
the value stored in <CODE>y</CODE>
|
||
to add it to the value stored in <CODE>x</CODE>.</P>
|
||
|
||
<P>Sequence points can also occur within expressions. The
|
||
<I><A HREF="#Comma">comma</A>,
|
||
<A HREF="#Conditional">conditional</A>,
|
||
<A HREF="#Function Call">function call</A>,
|
||
<A HREF="#Logical AND">logical AND</A>,</I> and
|
||
<I><A HREF="#Logical OR">logical OR</A></I>
|
||
operators each contain a sequence point. For example, you can write:</P>
|
||
|
||
<PRE>
|
||
if ((c = getchar()) != EOF && isprint(c))</PRE>
|
||
|
||
<P>and know that the program evaluates <CODE>isprint(c)</CODE> only after
|
||
a new value is stored in <CODE>c</CODE>
|
||
from the call to <CODE>getchar</CODE>.</P>
|
||
|
||
<P>Between two sequence points, you must access the value stored
|
||
in an object whose contents you are altering only to determine the
|
||
new value to store, and store a value in an object no more than once.</P>
|
||
|
||
<P>For example:</P>
|
||
|
||
<PRE>
|
||
val = 10 * val
|
||
+ (c - '0'); <B>well defined</B>
|
||
i = ++i + 2; <B>NOT well defined</B></PRE>
|
||
|
||
<P>An expression can contain sequence points and still not have
|
||
a definite order of evaluation. In the example above, the expression
|
||
<CODE>f() + g()</CODE> contains a sequence point before each function call,
|
||
but the <I>add</I> operator imposes no ordering on the evaluation
|
||
of its operands.</P>
|
||
|
||
<HR>
|
||
<P>See also the
|
||
<B><A HREF="index.html#Table of Contents" tppabs="http://ccs.ucsd.edu/c/index.html#Table of Contents">Table of Contents</A></B> and the
|
||
<B><A HREF="_index.html" tppabs="http://ccs.ucsd.edu/c/_index.html">Index</A></B>.</P>
|
||
|
||
<P><I>
|
||
<A HREF="crit_pb.html" tppabs="http://ccs.ucsd.edu/c/crit_pb.html">Copyright</A> © 1989-1996
|
||
by P.J. Plauger and Jim Brodie. All rights reserved.</I></P>
|
||
|
||
</BODY></HTML>
|
||
|