В C99 равенство ==
, кажется, никогда не бывает неопределенным.Он может выдать 1
случайно, если вы примените его к недействительным адресам (например, &x + 1 == &y
может быть истинным случайно).Это не приводит к неопределенному поведению.Многие, но не все, недопустимые адреса не определены для вычисления / использования в соответствии со стандартом, так что в p == &x
с p
висящим указателем или в &x + 2 == &y
недопустимый адрес вызывает неопределенное поведение, а не ==
.
С другой стороны, >=
и другие сравнения не определены, когда применяются к указателям, которые не указывают в пределах одного и того же объекта.Это включает в себя тестирование q >= NULL
, где q
является действительным указателем.Этот тест является предметом моего вопроса.
Я работаю над статическим анализатором низкоуровневого встроенного кода.Для этого вида кода нормально делать что-то, что не соответствует стандарту.Например, массив указателей в коде такого типа может быть инициализирован с помощью memset(...,0,...)
, хотя в стандарте не указывается, что NULL
и 0
должны иметь одинаковое представление.Чтобы быть полезным, анализатор должен принять такие вещи и интерпретировать их так, как ожидает программист.Предупреждение, что программист будет восприниматься как ложное срабатывание.
Таким образом, анализатор уже предполагает, что NULL
и 0
имеют одинаковое представление (вы должны проверить свой компилятор относительно анализатора, чтобы убедиться, что онисогласен с такого рода предположениями).Я заметил, что некоторые программы сравнивают действительные указатели с NULL с >=
( эта библиотека является примером).Это работает так, как задумано, если NULL
представлено как 0
, а сравнение указателей скомпилировано как сравнение целых чисел без знака.Я только хочу, чтобы анализатор предупредил об этом, если, возможно, из-за агрессивной оптимизации, он может быть скомпилирован в нечто отличное от того, что программист имел в виду на обычных платформах.Отсюда мой вопрос: есть ли какой-нибудь пример программы, не оценивающей q >= NULL
как 1
, на платформе, где NULL
представлен как 0
?
ПРИМЕЧАНИЕ: этот вопрос не об использовании 0в контексте указателя, чтобы получить нулевой указатель.Предположение о представлении NULL
является реальным предположением, потому что в примере memset()
нет преобразования.