Search code examples
c++pointersvolatileconst-cast

Why const_cast away volatile only work for pointer


// OK!
volatile CString* a0;
CString* a1 = const_cast<CString *>(a0);

// error C2440: 'const_cast' : cannot convert from 'volatile CString' to 'CString'
volatile CString b0;
CString b1 = const_cast<CString>(b0);

I was wondering, why const_cast only work for pointer? How can I make the 2nd case to compile?


Solution

  • const_cast acts on pointers and references, to remove const and volatile qualifiers. It doesn't make sense to use it to cast to an object type, since then you would making a copy which need not have the same cv-qualifiers as the original anyway.

    Your second example will compile if you cast to a non-volatile reference:

    volatile CString b0;
    CString & b1 = const_cast<CString &>(b0);
    

    However, using that reference gives undefined behaviour, since the underlying object is itself volatile. You should only use const_cast to remove qualifications when you know that the underlying object does not have those qualifications (or in the case of removing const, when you know that the result won't be used to modify the object).

    You can only get a copy if the object allows copying of volatile objects (perhaps with a copy constructor taking a reference-to-volatile or a volatile-qualified function or conversion operator). If CString doesn't provide any of these, then you can't safely copy a volatile object of that type.