Сравнить void* с uint16_t
В некотором устаревшем коде, который прекрасно компилируется на GCC 4.6 (с -fpermissive
), У меня есть это:
uint16_t a = 0;
void* b = ...;
if(b == a) // ...
Это сравнение хорошо определено в GCC 4.6? Уменьшается ли он до 16 или 32/64?
3 ответа
Похоже, что оно приводит к 16-битному целому числу, чтобы соответствовать размеру указателя. Запуск следующих кодовых выходов "upcast"
uint16_t a = 1;
void* b = (void*)0x10001;
(b == a) ? printf("downcast") : printf("upcast");
Хотя это явно не написано в стандарте C++11 (черновик N3337), я смог придумать это (выделение мое).
§5.9. Реляционные операторы
Указатели на объекты или функции одного и того же типа (после преобразования указателей) можно сравнивать, а результат определяется следующим образом.
- Если два указателя...
- Если два указателя...
- Если два указателя...
- Если два указателя...
- Если два указателя...
- Другие сравнения указателей не определены.
Теперь о равенстве:
§5.10 Операторы равенства
Операторы == (равно) и!= (Не равно) имеют те же семантические ограничения, преобразования и тип результата, что и операторы отношения, за исключением их более низкого приоритета и результата истинности.
Этим я считаю, что такое сравнение не уточняется.
Он может скомпилироваться или не сработать (не уверен, это зависит от параметров компилятора и компилятора). В любом случае приведение будет выполнено следующим образом:
if( b == (void*)a )
{
}
Обратите внимание, что upcasting/downcasting не является правильным словом для использования, потому что оно относится к классам, в данном случае это просто преобразования типов.