TL; DR:
void
указатели (базовый выпуск 879, посмотрите конец этого сообщения); void
указатели были добавлены в C++ 11 для разрешения его, но это в свою очередь дало начало двум другим проблемам ядра 583 & 1512 (см. ниже); void *
сравнение. Базовый Выпуск 583: Реляционные сравнения указателя с нулевым указателем, постоянным
- Реляционные сравнения указателя с нулевым указателем постоянный Раздел: 8,9 [expr.rel]
В C, это плохо формируется (cf C99 6.5.8):
void f(char* s) { if (s < 0) { } } ...but in C++, it's not. Why? Who would ever need to write (s > 0) when they could just as well write (s != 0)?
Это было на языке начиная с ARM (и возможно ранее); по-видимому, это - потому что преобразования указателя (7.11 [conv.ptr]) должны быть выполнены на обоих операндах каждый раз, когда один из операндов имеет тип указателя. Таким образом, похоже, что "null-ptr-to-real-pointer-type" преобразование цепляет поездку с другими преобразованиями указателя.
Предложенное разрешение (апрель 2013):
Этот вопрос решен разрешением [1 151] Выпуск 1512 Ядра выпуска 1512 .
: сравнение Указателя по сравнению с преобразованиями квалификации
<час>
- сравнение Указателя по сравнению с Разделом преобразований квалификации: 8,9 [expr.rel]
Согласно 8,9 [expr.rel] абзацам 2, описывая сравнения указателя,
преобразования Указателя (7.11 [conv.ptr]) и преобразования квалификации (7.5 [conv.qual]) выполняются на операндах указателя (или на операнде указателя и постоянном нулевом указателе, или на двух константах нулевого указателя, по крайней мере одна из которых является неинтегралом) принести им к их составному типу указателя. Это, казалось бы, сделало бы следующий пример плохо сформированным,
bool foo(int** x, const int** y) { return x < y; // valid ? } because int** cannot be converted to const int**, according to the rules of 7.5 [conv.qual] paragraph 4.
Это кажется слишком строгим для сравнения указателя, и текущие реализации принимают пример.
Предложенное разрешение (ноябрь 2012):
Соответствующие выборки от [1 152] разрешение вышеупомянутых проблем найдены в газете: сравнение Указателя по сравнению с преобразованиями квалификации (пересмотр 3) .
следующее также разрешает ядро Изменение выпуска 583 .
в 5,9 expr.rel абзацах 1 - 5:
В этом разделе следующее утверждение ( нечетный пункт в C++ 11 ) было , вычеркнул :
Указатели на
void
(после преобразований указателя) могут быть сравнены с результатом, определенным следующим образом: Если оба указателя представляют тот же адрес или являются оба значением нулевого указателя, результатtrue
, если оператор<=
или>=
иfalse
иначе; иначе результат неуказанный
, И следующие утверждения были , добавил :
- , Если два указателя указывают на различные элементы того же массива, или к подобъектам этого, указатель на элемент с более высоким нижним индексом выдерживает сравнение больше.
- , Если один указатель указывает на элемент массива, или к подобъекту этого, и другой указатель указывает на одно прошлое последний элемент массива, последний указатель выдерживает сравнение больше.
Так в заключительном рабочем проекте C++ 14 (n4140) раздел [expr.rel]/3, вышеупомянутые операторы найдены, поскольку они были указаны во время разрешения.
<час>Рытье по причине, почему этот нечетный пункт был добавлен, привело меня к намного более раннему выпуску 879: Недостающие встроенные операторы сравнения для типов указателей . Предложенное разрешение этой проблемы (в июле 2009) ведомый к добавлению этого пункта, который был выбран в WP в октябре 2009.
И именно так это стало включенным в C++ 11 стандартов.