В некоторых ситуациях крайне желательно, чтобы компилятор предупреждал или выдавал ошибку в коде, подобном reinterpret_cast<void*>(true)
, даже если этот код, по-видимому, является допустимым C ++. Например, это помогает в портировании на 64-битные платформы.
Преобразование 64-битного указателя в целочисленный тип, который меньше указателя (например, int
или bool
), часто является ошибкой: вы усекаете значение указателя. Кроме того, спецификация C ++, похоже, не гарантирует, что вы можете напрямую привести указатель к меньшему целочисленному типу (выделение добавлено):
5.2.10.4. Указатель может быть явно преобразован в любой целочисленный тип , достаточно большой, чтобы удерживать его . Функция отображения определяется реализацией.
Аналогично, преобразование меньшего целочисленного типа в 64-битный указатель (как с reinterpret_cast<void*>(true)
) также часто является ошибкой: компилятор должен заполнить верхние биты указателя чем-то; это заполнение нулями или расширение знака? Если вы не пишете низкоуровневый платформо-зависимый код для доступа к вводу-выводу в память или DMA, вы обычно вообще не хотите этого делать, если только вы не делаете что-то хакерское (например, вставляете логический указатель в указатель ). Но спецификация C ++, по-видимому, мало говорит об этом случае, кроме того, что она определяется реализацией (сноска опущена):
5.2.10.5. Значение целочисленного типа или типа перечисления может быть явно преобразовано в указатель. *
Указатель, преобразованный в целое число достаточного размера (если таковое существует в реализации) и обратно в тот же тип указателя, будет иметь свое первоначальное значение; Отображения между указателями и целыми числами определяются реализацией.
@ monjardin предложил reinterpret_cast<void*>(static_cast<int>(true))
. Если источником ошибки было несоответствие между размером целого типа и размером указателя, то это будет работать на большинстве 32-битных платформ (где int
и void*
являются 32-битными), но не на большинстве 64-битных платформы (где int
- 32 бита, а void*
- 64 бита). В этом случае замена int
в этом выражении на целочисленный тип размера указателя, такой как uintptr_t
или DWORD_PTR
(в Windows), должна работать, поскольку разрешены преобразования между bool
и целыми числами размера указателя, и поэтому преобразования между целыми числами и указателями размером с указатель.
Более поздние версии GCC имеют следующие опции подавления предупреждений , но не для C ++ :
-Wno-int-to-pointer-cast (только C и Objective-C)
Подавить предупреждения от приведения к типу указателя целого числа другого размера.
-Wno-pointer-to-int-cast (только C и Objective-C)
Подавить предупреждения от приведений из указателя на целочисленный тип другого размера.