Я столкнулся со странной ошибкой, связанной с reinterpret_cast. Просто посмотрите на код ниже:
int* var;
reinterpret_cast<void const **>(&var);
ошибка в VSC ++ 2010: ошибка C2440: «reinterpret_cast»: невозможно преобразовать из «int **» в «const void **»
ошибка в gcc 4.1.2: reinterpret_cast от типа «int **» до типа «const void **» отбрасывает константу
ошибка в gcc 4.6.2: reinterpret_cast из типа «int **» в тип «const void **» отбрасывает квалификаторы
Кто-нибудь знает, почему компиляторы говорят, что я отбрасываю const? Я и немногие из моих коллег по работе понятия не имеют, что с этим не так.
Спасибо за помощь!
Раздел 5.2.10 стандарта C ++ 03 говорит о том, что может делать reinterpret_cast. В нем прямо говорится: «Оператор reinterpret_cast не должен отбрасывать постоянство».
Константность отбрасывания определена в разделе 5.2.11 стандарта C ++ 03. Используемые здесь обозначения немного сбивают с толку, но в основном они утверждают, что приведение между двумя типами «отбрасывает константность», если не существует неявного преобразования для данной квалификации.
В вашем случае вы пытаетесь преобразовать int **
к void const**
, Компилятор спрашивает: «Могу ли я неявно конвертировать между T **
а также T const**
? «, и ответ — нет, поэтому он говорит, что вы отбрасываете постоянство.
Логика здесь в том, что reinterpret_cast сделан для обработки меняющихся типов, а не изменяющих квалификаторы (для этого и нужен const_cast). Так что, если вы просите его сделать что-то, для чего вам нужен const_cast, он отказывается.
Добавить / удалить const
использовать const_cast
,
Чтобы справиться с запутанными ошибками приведения, делайте вещи по одному шагу за раз:
int* var;
int** v2 = &var;
int const** v3 = const_cast<int const**>(v2);
void const** v4 = reinterpret_cast<void const**>(v3);
Обратите внимание, что int const**
и int**
очень разные типы, и преобразование между ними опасно — более опасно, чем void*
<-> int*
,
Предположим, у вас есть int** bob
, Затем вы передаете его функции, которая принимает int const** alice
через const_cast
,
В этой функции они назначают указатель на int, хранящийся в постоянной памяти, *alice
— совершенно законно.
Вне функции вы проверяете, что bob
а также *bob
действительны, а затем назначить **bob
, и вы только что попытались записать в память только для чтения.