Арифметика указателя массива — допустимое и неопределенное поведение

Я спрашивал себя, могут ли эти строки кода привести к неопределенному поведению в C и C ++.
Я пытался ответить на каждую точку, читая, что стандарт говорит о подписке массива (C 6.5.6 — 8). Я не опубликовал весь абзац, потому что он довольно длинный.

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

   1  int a[10];
2  int b = a[9]; // ok
3  int c = a[10]; // UB
4  int* d = (a + 10); // ok
5  int* e = &a[10]; // ok from C99 (& and [] are ignored, pointer is not deferenced), // UB in pre C99
6  int* f = &a[11]; // ok from C99, UB in pre c99
int* g = a;
7  int* h = g + 15; // ok

Я думаю, что те же ответы должны быть действительными для C ++

Являются ли эти строки действительными в C и C ++, я неправильно понял стандарт?

3

Решение

Ни 6, ни 7 не являются действительными, потому что они не выполняют арифметику указателей внутри существующего массива (включая указатель «один за другим»). Все остальное по сути правильно.

Только в C: учитывая, что a[i] идентично *(a + i), а также &*p всегда просто p без оценки *p, 5 всегда должно быть хорошо, хотя вы правы, что C89 не указывает это, и это было добавлено только в C99. (Это совсем не так в C ++, где операторы могут быть перегружены и нет упоминания о комбинировании & а также *.)

От n1570 (черновик до C11), в пункте 8 6.5.6 Аддитивные операторы:

[…] Если и операнд указателя, и результат [из P + N] указывают на элементы одного и того же объекта массива или одного элемента после последнего элемента объекта массива, при оценке не должно быть переполнения; в противном случае поведение не определено. […]

C ++ содержит очень похожие формулировки (например, C ++ 11, 5.7 / 5).

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]