reinterpret_cast — странное поведение

Я столкнулся со странной ошибкой, связанной с 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? Я и немногие из моих коллег по работе понятия не имеют, что с этим не так.

Спасибо за помощь!

4

Решение

Раздел 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, он отказывается.

8

Другие решения

Добавить / удалить 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, и вы только что попытались записать в память только для чтения.

2

По вопросам рекламы [email protected]