Files
2025-10-25 03:02:53 +03:00

137 lines
6.2 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.4Usual 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.7Integral 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.6Additive operators[expr.add]")
[*multiplicative-expression*](expr.mul#nt:multiplicative-expression "7.6.5Multiplicative operators[expr.mul]")
[*additive-expression*](#nt:additive-expression "7.6.6Additive operators[expr.add]") + [*multiplicative-expression*](expr.mul#nt:multiplicative-expression "7.6.5Multiplicative operators[expr.mul]")
[*additive-expression*](#nt:additive-expression "7.6.6Additive operators[expr.add]") - [*multiplicative-expression*](expr.mul#nt:multiplicative-expression "7.6.5Multiplicative 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.5Arrays")),[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−‰¤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.1Header <cstddef> synopsis[cstddef.syn]") header ([[support.types.layout]](support.types.layout "17.2.4Sizes, 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.1Preamble"))[.](#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.6Qualification 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.2Lvalue-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.4Compound 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)