[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)
