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

Другие вопросы по тегам