Search code examples
c++constantsvolatile

Can volatile be used everywhere const is used?


I wonder if volatile can be used anywhere const can, and what each case would mean.

volatile dummy_class
volatile dummy_class&
dummy_class volatile*
dummy_class *volatile
dummy_class volatile *volatile

These are all distinct cases when const is involved, do the same semantics apply for volatile?


Solution

  • This is section 3.9.3 CV-qualifiers from C++11 draft n3290:

    A type mentioned in 3.9.1 and 3.9.2 is a cv-unqualified type. Each type which is a cv-unqualified complete or incomplete object type or is void (3.9) has three corresponding cv-qualified versions of its type: a const-qualified version, a volatile-qualified version, and a const-volatile-qualified version. The term object type (1.8) includes the cv-qualifiers specified when the object is created. The presence of a const specifier in a decl-specifier-seq declares an object of const-qualified object type; such object is called a const object. The presence of a volatile specifier in a decl-specifier-seq declares an object of volatile-qualified object type; such object is called a volatile object. The presence of both cv-qualifiers in a decl-specifier-seq declares an object of const-volatile-qualified object type; such object is called a const volatile object. The cv-qualified or cv-unqualified versions of a type are distinct types; however, they shall have the same representation and alignment requirements (3.9).51

    So const and volatile can be used in the same spots, possibly in conjuction.

    Paragraph 3 of that section notes a slight difference in how they apply to class objects:

    Each non-static, non-mutable, non-reference data member of a const-qualified class object is const-quali- fied, each non-static, non-reference data member of a volatile-qualified class object is volatile-qualified and similarly for members of a const-volatile class. See 8.3.5 and 9.3.2 regarding function types that have cv-qualifiers.

    but that's pretty logical.

    volatile-qualified objects have stricter requirements for the as-if rule, namely:

    Access to volatile objects are evaluated strictly according to the rules of the abstract machine.

    The volatility gets attached to the object in the same way const does:

    dummy_class volatile* // non-volatile pointer to volatile object
    dummy_class *volatile // volatile pointer to non-volatile object
    dummy_class volatile *volatile // volatile pointer to volatile object
    

    For non-static member functions (§9.3.1):

    A non-static member function may be declared const, volatile, or const volatile. These cv-qualifiers affect the type of the this pointer (9.3.2). They also affect the function type (8.3.5) of the member function; a member function declared const is a const member function, a member function declared volatile is a volatile member function and a member function declared const volatile is a const volatile member function.

    So volatility like const-ness applies to the type of this inside the function.

    Neither const nor volatile can be applied to static member functions.