В некотором устаревшем коде, который прекрасно компилируется на GCC 4.6 (с -fpermissive
), У меня есть это:
uint16_t a = 0;
void* b = ...;
if(b == a) // ...
Это сравнение хорошо определено в GCC 4.6? Это понижается до 16 бит или повышается до 32/64 бит?
Похоже, что оно приводит к 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 не является правильным словом для использования, потому что оно относится к классам, в данном случае это просто преобразования типов.