[expr.unary.op]

# 7 Expressions [[expr]](./#expr)

## 7.6 Compound expressions [[expr.compound]](expr.compound#expr.unary.op)

### 7.6.2 Unary expressions [[expr.unary]](expr.unary#op)

#### 7.6.2.2 Unary operators [expr.unary.op]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5219)

The unary * operator performs [*indirection*](#def:indirection "7.6.2.2 Unary operators [expr.unary.op]")[.](#1.sentence-1)

Its operand shall be a prvalue of type âpointer to Tâ,
where T is an object or function type[.](#1.sentence-2)

The operator yields an lvalue of type T[.](#1.sentence-3)

If the operand points to an object or function,
the result denotes that object or function;
otherwise, the behavior is undefined except as specified in [[expr.typeid]](expr.typeid "7.6.1.8 Type identification")[.](#1.sentence-4)

[*Note [1](#note-1)*:

Indirection through a pointer to an out-of-lifetime object is valid ([[basic.life]](basic.life "6.8.4 Lifetime"))[.](#1.sentence-5)

â *end note*]

[*Note [2](#note-2)*:

Indirection through a pointer to an incomplete type (other thancv void) is valid[.](#1.sentence-6)

The lvalue thus obtained can be
used in limited ways (to initialize a reference, for example); this
lvalue must not be converted to a prvalue, see [[conv.lval]](conv.lval "7.3.2 Lvalue-to-rvalue conversion")[.](#1.sentence-7)

â *end note*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5241)

Each of the following unary operators yields a prvalue[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5244)

The operand of the unary & operator
shall be an lvalue of some type T[.](#3.sentence-1)

- [(3.1)](#3.1)

  If the operand is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") or [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") designating a non-static member m,
other than an explicit object member function,m shall be a direct member of some class C that is not an anonymous union[.](#3.1.sentence-1)
  The result has type âpointer to member of class C of type Tâ
and designates C​::​m[.](#3.1.sentence-2)
  [*Note [3](#note-3)*:
  A [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") that names a member of a namespace-scope anonymous union
is considered to be a class member access expression ([[expr.prim.id.general]](expr.prim.id.general "7.5.5.1 General"))
and cannot be used to form a pointer to member[.](#3.1.sentence-3)
 â *end note*]

- [(3.2)](#3.2)

  Otherwise, the result has type âpointer to Tâ and points to
the designated object ([[intro.memory]](intro.memory "6.8.1 Memory model")) or function ([[basic.compound]](basic.compound "6.9.4 Compound types"))[.](#3.2.sentence-1)
  If the operand designates an explicit object member function ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")),
the operand shall be
a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") or a [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]")[.](#3.2.sentence-2)
  [*Note [4](#note-4)*:
  In particular, taking the address of a variable of type âcv Tâ
yields a pointer of type âpointer to cv Tâ[.](#3.2.sentence-3)
 â *end note*]

[*Example [1](#example-1)*: struct A { int i; };struct B : A { };... &B::i ... // has type int A​::​*int a;int* p1 = &a;int* p2 = p1 + 1; // defined behaviorbool b = p2 > p1; // defined behavior, with value true â *end example*]

[*Note [5](#note-5)*:

A pointer to member formed from a mutable non-static data
member ([[dcl.stc]](dcl.stc "9.2.2 Storage class specifiers")) does not reflect the mutable specifier
associated with the non-static data member[.](#3.sentence-2)

â *end note*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5292)

A pointer to member is only formed when an explicit & is used
and its operand is
a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") or [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") not enclosed in parentheses[.](#4.sentence-1)

[*Note [6](#note-6)*:

That is, the expression &(qualified-id), where the[*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") is enclosed in parentheses, does not form an
expression of type âpointer to memberâ[.](#4.sentence-2)

Neither doesqualified-id, because there is no implicit conversion from a[*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") for a non-static member function to the type
âpointer to member functionâ as there is from an lvalue of function
type to the type âpointer to functionâ ([[conv.func]](conv.func "7.3.4 Function-to-pointer conversion"))[.](#4.sentence-3)

Nor is&unqualified-id a pointer to member, even within the scope of
the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]")'s class[.](#4.sentence-4)

â *end note*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5309)

If & is applied to an lvalue of incomplete class type and the
complete type declares operator&(), it is unspecified whether
the operator has the built-in meaning or the operator function is
called[.](#5.sentence-1)

The operand of & shall not be a bit-field[.](#5.sentence-2)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5315)

[*Note [7](#note-7)*:

The address of an overload set ([[over]](over "12 Overloading")) can be taken
only in a context that uniquely determines
which function is referred to (see [[over.over]](over.over "12.3 Address of an overload set"))[.](#6.sentence-1)

Since the context can affect whether the operand is a static or
non-static member function, the context can also affect whether the
expression has type âpointer to functionâ or âpointer to member
functionâ[.](#6.sentence-2)

â *end note*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5327)

The operand of the unary + operator shall be a prvalue of
arithmetic, unscoped
enumeration, or pointer type and the result is the value of the
argument[.](#7.sentence-1)

Integral promotion is performed on integral or enumeration
operands[.](#7.sentence-2)

The type of the result is the type of the promoted operand[.](#7.sentence-3)

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5335)

The operand of the unary - operator shall be a prvalue of
arithmetic or unscoped
enumeration type and the result is the negative of its operand[.](#8.sentence-1)

Integral
promotion is performed on integral or enumeration operands[.](#8.sentence-2)

The negative
of an unsigned quantity is computed by subtracting its value from 2n,
where n is the number of bits in the promoted operand[.](#8.sentence-3)

The type of the
result is the type of the promoted operand[.](#8.sentence-4)

[*Note [8](#note-8)*:

The result is the two's complement of the operand
(where operand and result are considered as unsigned)[.](#8.sentence-5)

â *end note*]

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5349)

The operand of the logical negation operator ! is contextually
converted to bool ([[conv]](conv "7.3 Standard conversions"));
its value is true if the converted operand is false and false otherwise[.](#9.sentence-1)

The type of the result is bool[.](#9.sentence-2)

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L5357)

The operand of the ~ operator shall be a prvalue of
integral or unscoped enumeration type[.](#10.sentence-1)

Integral promotions are performed[.](#10.sentence-2)

The type of the result is the type of the promoted operand[.](#10.sentence-3)

Given the coefficients xi of the base-2 representation ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))
of the promoted operand x,
the coefficient ri of the base-2 representation of the result r is 1 if xi is 0, and 0 otherwise[.](#10.sentence-4)

[*Note [9](#note-9)*:

The result is the ones' complement of the operand
(where operand and result are considered as unsigned)[.](#10.sentence-5)

â *end note*]

There is an ambiguity
in the grammar when ~ is followed by
a [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") or [*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]")[.](#10.sentence-6)

The ambiguity is resolved by treating ~ as the
operator rather than as the start of an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") naming a destructor[.](#10.sentence-7)

[*Note [10](#note-10)*:

Because the grammar does not permit an operator to follow the., ->, or ​::​ tokens, a ~ followed by
a [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") or [*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") in a
member access expression or [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") is
unambiguously parsed as a destructor name[.](#10.sentence-8)

â *end note*]
