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. Результат такий же.


Але чи 0вважається nullptrкомпілятором? Я думаю, що це йому цікаво. Принаймні, для мене це не має сенсу.
зміненоречовину

@alteredin substance 0 не "вважається" nullptr(або залежить від того, що ви маєте на увазі під врахуванням). 0 неявно перетворюється на std::nullptr_t.
eerorika

Це я припустив. Мені цікаво, чи є будь-яка документація щодо неявного перетворення 0на nullptr, оскільки я бачив лише дві сумісні з булевими порівняннями. Вони порівнянні, але я мав враження, що вони не конвертовані.
зміненаречовина

@alteredin substance Перетворення не відбувається навпаки. int x = nullptrнеправильно формується.
eerorika

2
@ alteredin substance 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значенням вказівника).


Це не обов'язково повертати 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 Якщо явно не задається питанням про те, що говорить Стандарт (через тег мови-юриста, наприклад), я намагаюся відповісти з практичної точки зору. Вся практична реалізація std::lessповернення false.
YSC

Це добре, я просто не вважаю ваші міркування (" як std :: менше це функціонер строгого порядку ") переконливим. Це може бути суворий порядок, не повертаючись false. Практичною причиною було б те, що нульове значення вказівника представлене найнижчою можливою адресою або чимось уздовж цих рядків.
волоський горіх
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.