Можно ли разыменовать один за указателем элемента, который сравнивается с действительным указателем? - PullRequest
4 голосов
/ 01 августа 2020

В C18 мы имеем:

§ 6.5.9p10

Два указателя сравниваются равными, если и только если оба являются нулевыми указателями, оба являются указателями на один и тот же объект (включая указатель на объект и подобъект в его начале) или функции, оба являются указателями на один за последним элементом одного и того же объекта массива, или один является указателем на один за концом одного объекта массива, а другой - указатель на начало другого объекта массива, который сразу же следует за первым объектом массива в адресном пространстве .

Итак, для int a[4][2] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}} мы можем иметь a[1] == a[0] + 2.

Может ли это впоследствии гарантировать, что *(a[1]) == *(a[0] + 2)?

1 Ответ

6 голосов
/ 01 августа 2020

Разыменовывать такой указатель не разрешается , даже если он сравнивается с другим действительным указателем.

Раздел 6.5.6p8 относительно оператора + утверждает:

Когда выражение с целочисленным типом добавляется к указателю или вычитается из него, результат имеет тип операнда указателя. Если операнд-указатель указывает на элемент объекта массива, а массив достаточно велик, результат указывает на смещение элемента от исходного элемента, так что разность индексов результирующего и исходного элементов массива равна целочисленному выражению. Другими словами, если выражение P указывает на i-й элемент объекта массива, выражения (P)+N (эквивалентно N+(P)) и (P)-N (где N имеет значение n ) указывают, соответственно, на i + n -й и i-n -й элементы объекта массива, если они существуют. Более того, если выражение P указывает на последний элемент объекта массива, выражение (P)+1 указывает на один за последним элементом объекта массива, и если выражение Q указывает на один за последним элементом массива объект, выражение (Q)-1 указывает на последний элемент объекта массива. Если и операнд-указатель, и результат указывают на элементы одного и того же объекта массива или один за последним элементом объекта массива, оценка не должна вызывать переполнения; в противном случае поведение не определено. Если результат указывает на один за последним элементом объекта массива, он не должен использоваться в качестве операнда унарного оператора *, который вычисляется

В связанных обратите внимание, что в некоторых компиляторах используется концепция происхождения указателя , что означает, что он внутренне отслеживает источник указателя. Следствием этого является то, что если две несвязанные переменные являются смежными в памяти, сравнение адреса одной с адресом другой всегда будет иметь значение false, даже если адреса совпадают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...