Гарантируется ли стандартом C, что, учитывая type_t* x = NULL; type_t* y = NULL;
, мы всегда имеем x > y
оценку как ложную? Я спрашиваю, потому что возможен разговор в начальном или конечном буфере malloc? из чего кажется, что следует быть осторожным со сравнением указателей и сравнивать только тогда, когда имеешь дело с указателями на элементы одного и того же массива, грубо говоря. Однако удобно иметь гарантированную оценку x > y
как false, потому что мне нужна структура, которая представляет собой стековой массив, имеющий поля для первого и послепоследнего элементов, и если этот массив все еще имеет элементы 0
, удобно установить эти поля должны быть NULL
, и удобно по-прежнему разрешать for
цикл по элементам массива, не проверяя явно, есть ли в массиве 0
элементы или больше, поэтому такое сравнение удобно...
@user17732522 user17732522 да, извини, я имею в виду последнее, отредактировано соответствующим образом...
Удивительно, но в C это вызывает неопределенное поведение. Только ==
и !=
могут работать с нулевыми указателями. Обходной путь — привести указатели к uintptr_t
и сравнить результаты.
C17 6.5.8 Операторы отношения /5
При сравнении двух указателей результат зависит от относительных расположений в адресном пространстве. объектов, на которые указывает. Если два указателя на типы объектов указывают на один и тот же объект или оба указывают один за последним элементом одного и того же объекта массива, они сравниваются равными. Если предметы указывали на являются членами одного и того же агрегатного объекта, указатели на члены структуры, объявленные позже, сравниваются больше, чем указатели на члены, объявленные ранее в структуре, и указатели на элементы массива с большими значениями индексов сравнивайте больше указателей с элементами того же массива с меньшими значениями. значения индексов. Все указатели на члены одного и того же объекта объединения сравниваются равными. Если выражение P указывает на элемент объекта массива, а выражение Q указывает на последний элемент того же объекта. объект массива, выражение указателя Q+1 сравнивается больше, чем P. Во всех остальных случаях поведение неопределенный.
(bold mine)
В этом отличие от C++, где есть пункт, в котором явно говорится, что <
,<=
,>
,>=
согласуются с ==
,!=
:
Если два операнда
p
иq
сравниваются равными ([expr.eq]),p<=q
иp>=q
оба даютtrue
, аp<q
иp>q
оба даютfalse
. ...
Однако то, является ли NULL
типом указателя, определяется реализацией. Оно может быть цельным и тогда false
гарантировано. И в C++, а также, предположительно, в C23, он также может не скомпилироваться, если NULL
имеет тип nullptr_t
.
@user17732522 Ммм, но никто не будет сравнивать NULL
напрямую. OP, скорее всего, означает, что у них есть переменные-указатели, которым они присваивают NULL
.
Да, вопрос, к сожалению, неточен в том, что он хочет спросить.
@user17732522 user17732522 не определен, а реализация не определена.
@HolyBlackCat да, извините, я соответствующим образом отредактировал вопрос, я имею в виду переменные, которым назначены NULL
.
@0___________ Нет, определение реализации означает, что реализация должна сделать выбор и задокументировать его (и существует только ограниченный набор допустимых вариантов выбора). Согласно этому ответу, поведение прямого сравнения NULL > NULL
будет неопределенным только в том случае, если реализация сделает определённый реализацией выбор использования (void*)0
(или аналогичного) в качестве определения NULL
.
@0___________ Я не уверен, что стандарт C говорит об отношении неопределенного поведения и поведения, определяемого реализацией, но, по крайней мере, в стандарте C++ поведение, определяемое реализацией, четко указано как параметризация набора абстрактных машин, тогда как неопределенное поведение свойство конкретных экземпляров параметризации этой абстрактной машины (с заданными входными данными).
@user17732522 user17732522 Как C++ связан с этим вопросом?
@ 0___________ Это не так, за исключением того, что в этом ответе об этом упоминается, и я более знаком с ним.
Вам следует подумать, действительно ли вы хотите спросить, гарантированно ли
NULL > NULL
как выражение оценивается какfalse
, или вы хотите спросить, гарантированно лиX > Y
где обаX
иY
являются значениями нулевого указателя (одного и того же типа) оцениваются какfalse
. Это совсем другие вопросы. (В частности,NULL
вообще не является значением нулевого указателя, а является константой нулевого указателя.)