Search code examples
c++type-conversionlanguage-lawyervolatile

Why is volatile int convertible to int but volatile T is not convertible to T?


Consider the following code:

#include <iostream>
#include <type_traits>

struct type {};

int main(int argc, char* argv[]) {
    std::cout << std::is_convertible_v<volatile int, int> << " ";
    std::cout << std::is_convertible_v<volatile int, volatile int> << " ";
    std::cout << std::is_convertible_v<volatile type, type> << " ";
    std::cout << std::is_convertible_v<volatile type, volatile type> << std::endl;
    return 0;
}

It prints out

1 1 0 0

Why is volatile int convertible to int, but volatile type is not convertible to type? Why is a volatile type not even convertible to volatile type?

Is there a way to make a volatile class copyable?

Note: references to the C++ standard are welcome


Solution

  • The implicitly-declared default constructor for type has this signature

    type::type(type const&);
    

    The reference cannot bind to a volatile object, since that would discard qualifiers.

    [class.copy.ctor]

    7 The implicitly-declared copy constructor for a class X will have the form

    X::X(const X&)
    

    if each potentially constructed subobject of a class type M (or array thereof) has a copy constructor whose first parameter is of type const M& or const volatile M&. Otherwise, the implicitly-declared copy constructor will have the form

    X::X(X&)
    

    Either way, the compiler isn't going to implicitly-declare a constructor that takes a reference to a volatile object.

    The fact that the target object in the conversion is volatile too makes no difference. Such a conversion requires a copy constructor capable of binding to a volatile source.

    Fundamental types aren't copied by constructors, so this behavior doesn't restrict them.

    Is there a way to make a volatile class copyable?

    If it's required, you'd need to user-declared copy constructor that accepts by a reference to a const volatile object.