Поведение не определено.
C99 6.5.6 В параграфе 9 сказано:
Когда вычтены два указателя, оба должны указывать на элементытот же самый объект массива, или один после последнего элемента объекта массива;В результате получается разница индексов двух элементов массива.
Пункт 7 в том же разделе гласит:
Для целей этих операторов указатель наобъект, который не является элементом массива, ведет себя так же, как указатель на первый элемент массива длиной один с типом объекта в качестве его типа элемента.
Раздел 4, абзац 2говорит:
Если требование «должен» или «не должен», которое появляется вне ограничения, нарушается, поведение не определено.Неопределенное поведение иначе обозначено в этом международном стандарте словами «неопределенное поведение» или пропуском любого явного определения поведения.Нет разницы в акценте между этими тремя;все они описывают «поведение, которое не определено».
3.4.3 определяет термин «неопределенное поведение» как:
поведение при использовании непереносимой или ошибочной программыконструировать или ошибочных данных, для которых этот международный стандарт не предъявляет никаких требований
ПРИМЕЧАНИЕ Возможные неопределенные варианты поведения варьируются от полного игнорирования ситуации с непредсказуемыми результатами до поведения во время перевода или выполнения программы документированным образом, характерным для среды (сили без выдачи диагностического сообщения), чтобы прекратить перевод или выполнение (с выдачей диагностического сообщения).
С учетом объявления:
int a = 5, b = 10, c;
это вероятночто оценка &b - &a
даст разумный результат, такой как 1
или -1
.(Разумные результаты всегда являются возможным признаком неопределенного поведения; оно не определено, не требует аварийного завершения.) Но компилятор не обязан помещать a
и b
в какие-либо конкретные места в памяти относительно друг друга, и дажеесли это так, вычитание не гарантированно будет значимым.Оптимизирующий компилятор может свободно преобразовывать вашу программу таким образом, чтобы предполагал , что ее поведение хорошо определено, что приводит к коду, который может вести себя произвольно плохим образом, если это предположение нарушается.&b - &a
, вы фактически обещаете компилятору, что это значимая операция.Как сказал Генри Спенсер: «Если вы лжете компилятору, он получит месть».
Обратите внимание, что это не просто результат вычитания, который является неопределенным, это поведение изпрограмма, которая его оценивает.
О, я упоминал, что поведение не определено?