Why does MSVC's STL implementation cast to const volatile char* here?
I was looking through some of the standard library's implementation for the usual containers (vector
, unordered_map
, etc...) when I came across the following, in the xutility
header:
template <class _CtgIt, class _OutCtgIt>
_OutCtgIt _Copy_memmove(_CtgIt _First, _CtgIt _Last, _OutCtgIt _Dest) {
auto _FirstPtr = _To_address(_First);
auto _LastPtr = _To_address(_Last);
auto _DestPtr = _To_address(_Dest);
const char* const _First_ch = const_cast<const char*>(reinterpret_cast<const volatile char*>(_FirstPtr));
const char* const _Last_ch = const_cast<const char*>(reinterpret_cast<const volatile char*>(_LastPtr));
char* const _Dest_ch = const_cast<char*>(reinterpret_cast<const volatile char*>(_DestPtr));
const auto _Count = static_cast<size_t>(_Last_ch - _First_ch);
_CSTD memmove(_Dest_ch, _First_ch, _Count);
if constexpr (is_pointer_v<_OutCtgIt>) {
return reinterpret_cast<_OutCtgIt>(_Dest_ch + _Count);
} else {
return _Dest + (_LastPtr - _FirstPtr);
}
}
Does anybody know why _First_ch
and _Last_ch
are first cast to const volatile char*
type then immediately cast to const char*
? I'm assuming it's to stop the compiler from optimizing prematurely, for some specific cases, but no concrete examples come to mind.
Solution 1:
If the target type of the pointer is volatile
-qualified, it is not possible to use reinterpret_cast
to directly cast to const char*
.
reinterpret_cast
is not allowed to cast away const
or volatile
. const_cast
however can do this, while not being able to change the pointer's target type itself.
I think a C-style cast would also always work in this situation, but reasoning about it is a bit more difficult, since it attempts multiple C++-style conversion sequences, only the last of which is a reinterpret_cast
followed by a const_cast
.
It may be just a style choice to not use C-style casts here.