140 lines
6.1 KiB
Markdown
140 lines
6.1 KiB
Markdown
[expr.pre]
|
||
|
||
# 7 Expressions [[expr]](./#expr)
|
||
|
||
## 7.1 Preamble [expr.pre]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L18)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
[[expr]](expr "7 Expressions") defines the syntax, order of evaluation, and meaning
|
||
of expressions[.](#1.sentence-1)[39](#footnote-39 "The precedence of operators is not directly specified, but it can be derived from the syntax.")
|
||
|
||
An expression is a sequence of operators and operands that specifies a
|
||
computation[.](#1.sentence-2)
|
||
|
||
An expression can result in a value and can cause side
|
||
effects[.](#1.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L32)
|
||
|
||
[*Note [2](#note-2)*:
|
||
|
||
Operators can be overloaded, that is, given meaning when applied to
|
||
expressions of <class> type or[enumeration](dcl.enum "9.8.1 Enumeration declarations [dcl.enum]") type[.](#2.sentence-1)
|
||
|
||
Uses of overloaded operators are transformed into
|
||
function calls as described in [[over.oper]](over.oper "12.4 Overloaded operators")[.](#2.sentence-2)
|
||
|
||
Overloaded operators
|
||
obey the rules for syntax and evaluation order specified in [[expr.compound]](expr.compound "7.6 Compound expressions"),
|
||
but the requirements of operand type and value category are replaced
|
||
by the rules for function call[.](#2.sentence-3)
|
||
|
||
Relations between operators, such as++a meaning a += 1, are not guaranteed for [overloaded
|
||
operators](over.oper "12.4 Overloaded operators [over.oper]")[.](#2.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L46)
|
||
|
||
Subclause [[expr.compound]](expr.compound "7.6 Compound expressions") defines the effects of operators when applied to types
|
||
for which they have not been overloaded[.](#3.sentence-1)
|
||
|
||
Operator overloading shall not
|
||
modify the rules for the [*built-in operators*](#def:operators,built-in "7.1 Preamble [expr.pre]"),
|
||
that is, for operators applied to types for which they are defined by this
|
||
Standard[.](#3.sentence-2)
|
||
|
||
However, these built-in operators participate in overload
|
||
resolution, and as part of that process user-defined conversions will be
|
||
considered where necessary to convert the operands to types appropriate
|
||
for the built-in operator[.](#3.sentence-3)
|
||
|
||
If a built-in operator is selected, such
|
||
conversions will be applied to the operands before the operation is
|
||
considered further according to the rules in [[expr.compound]](expr.compound "7.6 Compound expressions");
|
||
see [[over.match.oper]](over.match.oper "12.2.2.3 Operators in expressions"), [[over.built]](over.built "12.5 Built-in operators")[.](#3.sentence-4)
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L59)
|
||
|
||
If during the evaluation of an expression, the result is not
|
||
mathematically defined or not in the range of representable values for
|
||
its type, the behavior is undefined[.](#4.sentence-1)
|
||
|
||
[*Note [3](#note-3)*:
|
||
|
||
Treatment of division by zero, forming a remainder using a zero divisor,
|
||
and all floating-point exceptions varies among machines, and is sometimes
|
||
adjustable by a library function[.](#4.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L75)
|
||
|
||
[*Note [4](#note-4)*:
|
||
|
||
The implementation can regroup operators according to
|
||
the usual mathematical rules only
|
||
where the operators really are associative or commutative[.](#5.sentence-1)[40](#footnote-40 "Overloaded operators are never assumed to be associative or commutative.")
|
||
|
||
For example, in the following fragmentint a, b;/* ... */ a = a + 32760 + b + 5; the expression statement behaves exactly the same asa = (((a + 32760) + b) + 5); due to the associativity and precedence of these operators[.](#5.sentence-2)
|
||
|
||
Thus, the
|
||
result of the sum (a + 32760) is next added to b, and
|
||
that result is then added to 5 which results in the value assigned toa[.](#5.sentence-3)
|
||
|
||
On a machine in which overflows produce an exception and in
|
||
which the range of values representable by an int is
|
||
[-32768, +32767], the implementation cannot rewrite this
|
||
expression asa = ((a + b) + 32765); since if the values for a and b were, respectively,â32754 and â15, the sum a + b would produce an exception while
|
||
the original expression would not; nor can the expression be rewritten
|
||
as eithera = ((a + 32765) + b); ora = (a + (b + 32765)); since the values for a and b might have been,
|
||
respectively, 4 and â8 or â17 and 12[.](#5.sentence-4)
|
||
|
||
However on a machine in which
|
||
overflows do not produce an exception and in which the results of
|
||
overflows are reversible, the above expression statement can be
|
||
rewritten by the implementation in any of the above ways because the
|
||
same result will occur[.](#5.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L125)
|
||
|
||
The values of the floating-point operands and
|
||
the results of floating-point expressions
|
||
may be represented in greater precision and range than that
|
||
required by the type; the types are not changed
|
||
thereby[.](#6.sentence-1)[41](#footnote-41 "The cast and assignment operators must still perform their specific conversions as described in [expr.type.conv], [expr.cast], [expr.static.cast] and [expr.assign].")
|
||
|
||
[39)](#footnote-39)[39)](#footnoteref-39)
|
||
|
||
The precedence of operators is not directly specified, but it can be
|
||
derived from the syntax[.](#footnote-39.sentence-1)
|
||
|
||
[40)](#footnote-40)[40)](#footnoteref-40)
|
||
|
||
Overloaded
|
||
operators are never assumed to be associative or commutative[.](#footnote-40.sentence-1)
|
||
|
||
[41)](#footnote-41)[41)](#footnoteref-41)
|
||
|
||
The cast and assignment operators must still perform their specific
|
||
conversions as described in [[expr.type.conv]](expr.type.conv "7.6.1.4 Explicit type conversion (functional notation)"), [[expr.cast]](expr.cast "7.6.3 Explicit type conversion (cast notation)"),[[expr.static.cast]](expr.static.cast "7.6.1.9 Static cast") and [[expr.assign]](expr.assign "7.6.19 Assignment and compound assignment operators")[.](#footnote-41.sentence-1)
|