137 lines
6.2 KiB
Markdown
137 lines
6.2 KiB
Markdown
[expr.add]
|
||
|
||
# 7 Expressions [[expr]](./#expr)
|
||
|
||
## 7.6 Compound expressions [[expr.compound]](expr.compound#expr.add)
|
||
|
||
### 7.6.6 Additive operators [expr.add]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7108)
|
||
|
||
The additive operators + and - group left-to-right[.](#1.sentence-1)
|
||
|
||
Each operand shall be a prvalue[.](#1.sentence-2)
|
||
|
||
If both operands have arithmetic or unscoped enumeration type,
|
||
the usual arithmetic conversions ([[expr.arith.conv]](expr.arith.conv "7.4 Usual arithmetic conversions")) are performed[.](#1.sentence-3)
|
||
|
||
Otherwise, if one operand has arithmetic or unscoped enumeration type,
|
||
integral promotion is applied ([[conv.prom]](conv.prom "7.3.7 Integral promotions")) to that operand[.](#1.sentence-4)
|
||
|
||
A converted or promoted operand is used in place of
|
||
the corresponding original operand for the remainder of this section[.](#1.sentence-5)
|
||
|
||
[additive-expression:](#nt:additive-expression "7.6.6 Additive operators [expr.add]")
|
||
[*multiplicative-expression*](expr.mul#nt:multiplicative-expression "7.6.5 Multiplicative operators [expr.mul]")
|
||
[*additive-expression*](#nt:additive-expression "7.6.6 Additive operators [expr.add]") + [*multiplicative-expression*](expr.mul#nt:multiplicative-expression "7.6.5 Multiplicative operators [expr.mul]")
|
||
[*additive-expression*](#nt:additive-expression "7.6.6 Additive operators [expr.add]") - [*multiplicative-expression*](expr.mul#nt:multiplicative-expression "7.6.5 Multiplicative operators [expr.mul]")
|
||
|
||
For addition, either both operands shall have arithmetic
|
||
type, or one operand shall be a pointer to a completely-defined object
|
||
type and the other shall have integral type[.](#1.sentence-6)
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7137)
|
||
|
||
For subtraction, one of the following shall hold:
|
||
|
||
- [(2.1)](#2.1)
|
||
|
||
both operands have arithmetic type; or
|
||
|
||
- [(2.2)](#2.2)
|
||
|
||
both operands are pointers to cv-qualified or cv-unqualified
|
||
versions of the same completely-defined object type; or
|
||
|
||
- [(2.3)](#2.3)
|
||
|
||
the left operand is a pointer to a completely-defined object type
|
||
and the right operand has integral type[.](#2.sentence-1)
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7151)
|
||
|
||
The result of the binary + operator is the sum of the operands[.](#3.sentence-1)
|
||
|
||
The result of the binary - operator is the difference resulting
|
||
from the subtraction of the second operand from the first[.](#3.sentence-2)
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7156)
|
||
|
||
When an expression J that has integral type
|
||
is added to or subtracted from an expression P of pointer type,
|
||
the result has the type of P[.](#4.sentence-1)
|
||
|
||
- [(4.1)](#4.1)
|
||
|
||
If P evaluates to a null pointer value andJ evaluates to 0, the result is a null pointer value[.](#4.1.sentence-1)
|
||
|
||
- [(4.2)](#4.2)
|
||
|
||
Otherwise, if P points to a (possibly-hypothetical) array element i of an array object x with n elements ([[dcl.array]](dcl.array "9.3.4.5 Arrays")),[64](#footnote-64 "As specified in [basic.compound], an object that is not an array element is considered to belong to a single-element array for this purpose and a pointer past the last element of an array of n elements is considered to be equivalent to a pointer to a hypothetical array element n for this purpose.") the expressions P + J and J + P (where J has the value j)
|
||
point to the (possibly-hypothetical) array elementi+j of x if 0â¤i+jâ¤n and the expression P - J points to the (possibly-hypothetical) array elementiâj of x if 0â¤iâjâ¤n[.](#4.2.sentence-1)
|
||
|
||
- [(4.3)](#4.3)
|
||
|
||
Otherwise, the behavior is undefined[.](#4.3.sentence-1)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
Adding a value other than 0 or 1 to a pointer to a base class subobject, a member subobject,
|
||
or a complete object results in undefined behavior[.](#4.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7189)
|
||
|
||
When two pointer expressions P and Q are subtracted,
|
||
the type of the result is an implementation-defined signed
|
||
integral type; this type shall be the same type that is named bystd::ptrdiff_t in the [<cstddef>](cstddef.syn#header:%3ccstddef%3e "17.2.1 Header <cstddef> synopsis [cstddef.syn]") header ([[support.types.layout]](support.types.layout "17.2.4 Sizes, alignments, and offsets"))[.](#5.sentence-1)
|
||
|
||
- [(5.1)](#5.1)
|
||
|
||
If P and Q both evaluate to null pointer values,
|
||
the result is 0[.](#5.1.sentence-1)
|
||
|
||
- [(5.2)](#5.2)
|
||
|
||
Otherwise, if P and Q point to, respectively,
|
||
array elements i and j of the same array object x,
|
||
the expression P - Q has the value iâj[.](#5.2.sentence-1)
|
||
[*Note [2](#note-2)*:
|
||
If the value iâj is not in the range of representable values
|
||
of type std::ptrdiff_t,
|
||
the behavior is undefined ([[expr.pre]](expr.pre "7.1 Preamble"))[.](#5.2.sentence-2)
|
||
â *end note*]
|
||
|
||
- [(5.3)](#5.3)
|
||
|
||
Otherwise, the behavior is undefined[.](#5.3.sentence-1)
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7215)
|
||
|
||
For addition or subtraction, if the expressions P or Q have
|
||
type âpointer to cv Tâ, where T and the array element type
|
||
are not [similar](conv.qual#def:similar_types "7.3.6 Qualification conversions [conv.qual]"), the behavior is undefined[.](#6.sentence-1)
|
||
|
||
[*Example [1](#example-1)*: int arr[5] = {1, 2, 3, 4, 5};unsigned int *p = reinterpret_cast<unsigned int*>(arr + 1);unsigned int k = *p; // OK, value of k is 2 ([[conv.lval]](conv.lval "7.3.2 Lvalue-to-rvalue conversion"))unsigned int *q = p + 1; // undefined behavior: p points to an int, not an unsigned int object â *end example*]
|
||
|
||
[64)](#footnote-64)[64)](#footnoteref-64)
|
||
|
||
As specified in [[basic.compound]](basic.compound "6.9.4 Compound types"),
|
||
an object that is not an array element
|
||
is considered to belong to a single-element array for this purpose and
|
||
a pointer past the last element of an array of n elements
|
||
is considered to be equivalent to a pointer to a hypothetical array elementn for this purpose[.](#footnote-64.sentence-1)
|