unique_ptr <0 ИЛИ что делает меньше, чем оператор?

9

Я имею дело с кодом, который был написан не мной. У меня есть это утверждение:

// p is type of std::unique_ptr<uint8_t[]>
if (p < 0) { /* throw an exception */ }

Так что же p < 0значит в этом контексте?
На странице документации , я считаю, что мой случай 16) y < nullptr, где0 находится nullptr.

Но что это делает?

Саит
источник
1
Исходя из того факта, что в x64 канонические указатели в диапазоне ядра имеют верхний установленный бит, это может быть (глупо жестко) способ проверить, принадлежит ли указатель к пространству ядра - хотя ответ ниже верен, тогда нет ,
Майкл Чурдакис
1
В WINAPI p==-1есть неверный дескриптор. Поскольку 2^64это смешно огромное число, любое разумное pвсегда положительно. Так что p<0проверяет недействительный дескриптор WINAPI. Это не хороший код.
ALX23z
@OP: Не могли бы вы уточнить, в каком контексте этот код используется? Это используется в Linux или Windows? Связано ли значение указателя с каким-либо кодом WINAPI? Я думаю, что если вы уточнить это, комментарии выше могут быть хорошими ответами.
грецкий орех
@ ALX23z Но должен ли дескриптор WINAPI иметь тип uint8_t*(или даже массив uint8_t)? Я так думаю void*, не так ли?
грецкий орех
@walnut они не void*имеют макроса HANDLE_PTR или чего-то, что в основном является long*iirc.
ALX23z

Ответы:

2

unique_ptr <0 ИЛИ что делает меньше, чем оператор?

Это соответствует перегрузке (11) на cppreference operator<(const unique_ptr&, nullptr_t);. 0 неявно преобразуется в std::nullptr_t. Согласно документации, результат есть std::less<unique_ptr<T,D>::pointer>()(x.get(), nullptr).

Результат определяется реализацией, но безусловно ложен на большинстве систем. Предположительно в экзотической системе, где null не имеет двоичного представления 0, результат может быть истинным.

Я считаю, что мой случай 16)

(16) такой же , наоборот: 0 > unique_ptr. Результат тот же.

eerorika
источник
Но 0считается ли nullptrэто компилятором? Я думаю, это то, что ему интересно. По крайней мере, для меня это тоже не имеет смысла.
измененный экземпляр
@alteredinstance 0 не "считается" nullptr(или зависит от того, что вы подразумеваете под рассмотрением). 0 неявно преобразуется в std::nullptr_t.
eerorika
Это то, что я предположил. Мне интересно, есть ли какая-либо документация по неявному преобразованию 0в nullptr, поскольку я видел только два из них, совместимых с логическими сравнениями. Они сопоставимы, но у меня сложилось впечатление, что они не конвертируемые.
измененный экземпляр
@alteredinstance Конверсия не происходит наоборот. int x = nullptrплохо сформирован.
eerorika
2
@alteredinstance std::nullptr_tбыл разработан для использования с любой константой нулевого указателя; не просто nullptr. 0 (как и 0L, например) являются константами нулевого указателя, поэтому предполагается, что они могут быть использованы для создания std::nullptr_t.
eerorika
2

Убедитесь, что operator <не перегружен где-то в вашей кодовой базе. Это , кажется, единственный способ , как (p < 0)может бытьtrue .

Пример:

bool operator< (const std::unique_ptr<uint8_t[]>&, int) { return true; }

int main() {
    std::unique_ptr<uint8_t[]> p;
    std::cout << (p < 0) << std::endl;
}

Печать:

1

живое демо

В противном случае, как уже говорили другие, 0неявно преобразуется в std::nullptr_t, что выберет bool operator<(const unique_ptr<T, D>& x, nullptr_t)перегрузку, которая вызовет, std::less(p, 0)который будет возвращаться false(даже в Windows со -1значением указателя).

rustyx
источник
Это не обязательно возврат false. Он либо определяется реализацией, либо не указывается (я не уверен.) Но я согласен, что он, вероятно, вернется falseв большинстве (всех?) Реализаций. Смотрите также ответ @eerorika
грецкий орех
0

Это выражение совпадает с этим оператором шаблона (0 преобразуется в nullptr):

template <class T, class D>
bool operator<(const unique_ptr<T, D>& x, nullptr_t);

Это возвращает, std::less<unique_ptr<T,D>::pointer>()(p.get(), nullptr)что всегда ложно (как std::lessфунктор строгого порядка) ( демо ).

МКЦ
источник
Это не всегда возвращается false. Является ли это определенным для реализации или неопределенным. Вероятно, он всегда возвращается, falseхотя в большинстве (всех?) Текущих реализаций.
грецкий орех
@walnut Если вопрос прямо не спрашивает о том, что говорит Стандарт (например, через тег language-lawyer ), я пытаюсь ответить с практической точки зрения. Вся практическая реализация std::lessвозврата false.
YSC
Это нормально, я просто не нашел ваши рассуждения (" поскольку std :: less - строгий функтор порядка ") убедительны. Это может быть строгий порядок без возврата false. Практическая причина заключается в том, что нулевое значение указателя представлено наименьшим возможным адресом или чем-то в этом направлении.
грецкий орех