182 The semantic descriptions in this International Standard describe the behavior of an abstract machine in which issues of optimization are irrelevant.
183 Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects,11) which are changes in the state of the execution environment.
184 Evaluation of an expression may produce side effects.
185 At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place.
186 (A summary of the sequence points is given in annex C.)
187 In the abstract machine, all expressions are evaluated as specified by the semantics.
188 An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).
189 When the processing of the abstract machine is interrupted by receipt of a signal, only the values of objects as of the previous sequence point may be relied on.
190 Objects that may be modified between the previous sequence point and the next sequence point need not have received their correct values yet.
191 The least requirements on a conforming implementation are:
192 At sequence points, volatile objects are stable in the sense that previous accesses are complete and subsequent accesses have not yet occurred.
193
10) In accordance with 6.2.4, the lifetimes of objects with automatic
storage duration declared in
194 11) The IEC 60559 standard for binary floating-point arithmetic requires certain user-accessible status flags and control modes.
195 Floating-point operations implicitly set the status flags;
196 modes affect result values of floating-point operations.
197 Implementations that support such floating-point state are required to regard changes to it as side effects see annex F for details.
198
The floating-point environment library
199 At program termination, all data written into files shall be identical to the result that execution of the program according to the abstract semantics would have produced.
200 The input and output dynamics of interactive devices shall take place as specified in 7.19.3.
201 The intent of these requirements is that unbuffered or line-buffered output appear as soon as possible, to ensure that prompting messages actually appear prior to a program waiting for input.
202 What constitutes an interactive device is implementation-defined.
203 More stringent correspondences between abstract and actual semantics may be defined by each implementation.
204
EXAMPLE 1
An implementation might define a one-to-one correspondence between
abstract and actual semantics: at every sequence point, the values of
the actual objects would agree with those specified by the abstract
semantics. The keyword
Alternatively, an implementation might perform various optimizations
within each translation unit, such that the actual semantics would
agree with the abstract semantics only when making function calls
across translation unit boundaries. In such an implementation, at
the time of each function entry and function return where the calling
function and the called function are in different translation units,
the values of all externally linked objects and of all objects
accessible via pointers therein would agree with the abstract
semantics. Furthermore, at the time of each such function entry the
values of the parameters of the called function and of all objects
accessible via pointers therein would agree with the abstract
semantics. In this type of implementation, objects referred to by
interrupt service routines activated by the
205 EXAMPLE 2 In executing the fragment
char c1, c2;
/* ... */
c1 = c1 + c2;
the integer promotions require that the abstract
machine promote the value of each variable to
206 EXAMPLE 3 Similarly, in the fragment
float f1, f2;
double d;
/* ... */
f1 = f2 * d;
the multiplication may be executed using single-precision arithmetic
if the implementation can ascertain that the result would be the same
as if it were executed using double-precision arithmetic (for
example, if
207 EXAMPLE 4 Implementations employing wide registers have to take care to honor appropriate semantics. Values are independent of whether they are represented in a register or in memory. For example, an implicit spilling of a register is not permitted to alter the value. Also, an explicit store and load is required to round to the precision of the storage type. In particular, casts and assignments are required to perform their specified conversion. For the fragment
double d1, d2;
float f;
d1 = f = expression;
d2 = (float) expression;
the values assigned to
208 EXAMPLE 5 Rearrangement for floating-point expressions is often restricted because of limitations in precision as well as range. The implementation cannot generally apply the mathematical associative rules for addition or multiplication, nor the distributive rule, because of roundoff error, even in the absence of overflow and underflow. Likewise, implementations cannot generally replace decimal constants in order to rearrange expressions. In the following fragment, rearrangements suggested by mathematical rules for real numbers are often not valid (see F.8).
double x, y, z;
/* ... */
x = (x * y) * z; // not equivalent to x *= y * z;
z = (x - y) + y ; // not equivalent to z = x;
z = x + x * y; // not equivalent to z = x * (1.0 + y);
y = x / 5.0; // not equivalent to y = x * 0.2;
209 EXAMPLE 6 To illustrate the grouping behavior of expressions, in the following fragment
int a, b;
/* ... */
a = a + 32760 + b + 5;
the expression statement behaves exactly the same as
a = (((a + 32760) + b) + 5);
due to the associativity and precedence of these operators. Thus,
the result of the sum
a = ((a + b) + 32765);
since if the values for
a = ((a + 32765) + b);
or
a = (a + (b + 32765));
since the values for
210 EXAMPLE 7 The grouping of an expression does not completely determine its evaluation. In the following fragment
#include
int sum;
char *p;
/* ... */
sum = sum * 10 - '0' + (*p++ = getchar());
the expression statement is grouped as if it were written as
sum = (((sum * 10) - '0') + ((*(p++)) = (getchar())));
but the actual increment of
211 Forward references: expressions (6.5), type qualifiers (6.7.3), statements (6.8), the signal function (7.14), files (7.19.3).
Next
Created at: 2005-06-29 02:18:53
The text from WG14/N1124 is copyright © ISO