cv (const-volatility) specifiers and qualifiers - cppreference.com

##### cppreference.com

##### Search

Create account

##### Namespaces

- Page
- Discussion

##### Variants

##### Views

- View
- Edit
- History

##### Actions

# cv (const-volatility) specifiers and qualifiers

From cppreference.com
< cpp‎ | language

Appear in any type specifier, including decl-specifier-seq of declaration grammar, to specify constness or volatility of the type being declared.

  - `const` - defines that the type is constant.
  - `volatile` - defines that the type is volatile.
  - `mutable` - defines that a member of a class does not affect the externally visible state of the class. `mutable` members can be modified in constant classes, that is constness is essentially ignored for the particular member.

### [edit] Explanation

For any type `T` (including incomplete types), other than function type or reference type, there are three more distinct types in the C++ type system: const-qualified `T`, volatile-qualified `T`, and const-volatile-qualified `T`.

  Note: cv-qualifiers and cv-specifiers are not the same thing: cv-qualifiers are the properties of a type whereas cv-specifiers are the language keywords used to define cv-qualifiers.

  Note: array types are considered to have the same cv-qualification as their element types.

When an object is first created, the cv-specifiers used (which could be part of decl-specifier-seq or part of a declarator in a declaration, or part of type-id in a new-expression) determine the constness or volatility of the object, as follows:

- const object - an object whose type is const-qualified, or a non-mutable subobject of a const object. Such object cannot be modified: attempt to do so directly is a compile-time error, and attempt to do so indirectly (e.g., by modifying the const object through a reference or pointer to non-const type) results in undefined behavior.
- volatile object - an object whose type is volatile-qualified, or a subobject of a volatile object, or a mutable subobject of a const-volatile object. Every access (read or write operation, member function call, etc.) on the volatile object is treated as a visible side-effect for the purposes of optimization (that is, within a single thread of execution, volatile accesses cannot be reordered or optimized out. This makes volatile objects suitable for communication with a signal handler, but not with another thread of execution, see std::memory_order). Any attempt to refer to a volatile object through a non-volatile glvalue (e.g. through a reference or pointer to non-volatile type) results in undefined behavior.
- const volatile object - an object whose type is const-volatile-qualified, a non-mutable subobject of a const volatile object, a const subobject of a volatile object, or a non-mutable volatile subobject of a const object. Behaves as both a const object and as a volatile object.

There is partial ordering of cv-qualifiers by the order of increasing restrictions. The type can be said more or less cv-qualified then:

  - unqualified < `const`
  - unqualified < `volatile`
  - unqualified < `const volatile`
  - `const` < `const volatile`
  - `volatile` < `const volatile`

References and pointers to cv-qualified types may be implicitly converted to references and pointers to more cv-qualified types. In particular, the following conversions are allowed:

  - unqualified type can be converted to `const`
  - unqualified type can be converted to `volatile`
  - unqualified type can be converted to `const volatile`
  - `const` type can be converted to `const volatile`
  - `volatile` type can be converted to `const volatile`

  Note: additional restrictions are imposed on multi-level pointers.

To convert a reference or a pointer to a cv-qualified type to a reference or pointer to a less cv-qualified type, const_cast must be used.

### [edit] Keywords

`const`, `volatile`, `mutable`

### [edit] Example

Run this code

    int main()
    {
        int n1 = 0;           // non-const object
        const int n2 = 0;     // const object
        int const n3 = 0;     // const object (same as n2)
        volatile int n4 = 0;  // volatile object
        const struct X {
            int n1;
            mutable int n2;
        } x = {0, 0};      // const object with mutable member

        n1 = 1; // ok, modifiable obejct
    //  n2 = 2; // error: non-modifiable object
        n4 = 3; // ok, treated as a side-effect.
    //  x.n1 = 4; // error: member of a const object is const
        x.n2 = 4; // ok, mutable member of a const object isn't const

        const int& r1 = n1; // reference to const bound to non-const object
    //  r1 = 2; // error: attempt to modify through reference to const
        const_cast<int&>(r1) = 2; // ok, modifies n1

        const int& r2 = n2; // reference to const bound to const object
    //  r2 = 2; // error: attempt to modify through reference to const
    //  const_cast<int&>(r2) = 2; // undefined behavior: attempt to modify const object
    }

Output:

    # typical machine code produced on an x86_64 platform
    # (only the code that contributes to observable side-effects is emitted)
    main:
        movl    $0, -4(%rsp) # volatile int n4 = 0;
        movl    $3, -4(%rsp) # n4 = 3;
        xorl    %eax, %eax   # return 0 (implicit)
        ret

Retrieved from "http://en.cppreference.com/mwiki/index.php?title=cpp/language/cv&oldid=72026"