[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.syn#header:%3ccstddef%3e "17.2.1 Header 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(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)