Происходит ли следующее поведение undefined в строке 4 и/или 5:
#include <stdio.h>
int main(void)
{
char s[] = "foo";
char * p = s - 1; /* line 4 */
printf("%s\n", p + 1); /* line 5 */
return 0;
}
Происходит ли следующее поведение undefined в строке 4 и/или 5:
#include <stdio.h>
int main(void)
{
char s[] = "foo";
char * p = s - 1; /* line 4 */
printf("%s\n", p + 1); /* line 5 */
return 0;
}
Происходит ли следующее поведение undefined в строке 4 и/или 5:
Да, строка 4 undefined поведение, поскольку указатель не указывает на границы массива или один за границами массива. Хотя верно, чтобы указать один за границами массива, вы не можете разыменовать этот элемент.
Соответствующий раздел в черновик проекта c99 6.5.6
Аддитивные операторы, пункт 8:
Когда выражение, которое имеет целочисленный тип, добавляется или вычитается из указателя, result имеет тип операнда указателя. [...] Если оба операнда указателя и результат указывают на элементы одного и того же объекта массива или один за последним элементом объекта массива, оценка не должна приводить к переполнению; , поведение undefined.
В конце абзаца говорится, что вы не должны относиться к одному из последних элементов:
[...] Если результат указывает один за последний элемент объекта массива, он не должен использоваться как операнд унарного * оператора, который оценивается
Уменьшение указателя за пределами границ массива undefined.
C99 standard, пункт 6.5.6 в пункте 8, отчасти,
Когда выражение, которое имеет целочисленный тип, добавляется или вычитается из указателя, result имеет тип операнда указателя.... Если оба указателя операнд и результат указывают на элементы одного и того же объекта массива или один за последним элемент объекта массива, оценка не должна приводить к переполнению; в противном случае поведение не определено.
Итак, ваша строка 4 вызывает поведение undefined, так как результат не находится ни в массиве, ни в конце его.
Да, строка 4 - это поведение undefined!
C99 6.5.6 Аддитивные операторы, раздел 8
Когда выражение, которое имеет целочисленный тип, добавляется или вычитается из указателя, result имеет тип операнда указателя. Если операнд указателя указывает на элемент объект массива и массив достаточно велик, результат указывает на смещение элемента от исходный элемент такой, что разность индексов результирующих и исходных элементов массива равна целочисленному выражению. Другими словами, если выражение P указывает на элемент
i-th
объекта массива, выражения(P) + N
(эквивалентно,N + (P)
) и(P) - N
(гдеN
имеет значениеN
) указывают на, соответственно, элементыi+n-th
иi−n-th
объекта массива, если они существуют. Более того, если выражениеP
указывает на последний элемент объекта массива, выражение(P) + 1
указывает один за последним элементом объекта массива, а если выражениеQ
указывает один за последним элементом массива объект, выражение(Q) - 1
указывает на последний элемент объекта массива. Если оба операнда указателя и результат указывают на элементы одного и того же объекта массива или один за последним элементом объекта массива, оценка не должна приводить к переполнению; в противном случае поведение undefined. Если результат указывает один за последним элементом объекта массива, он не должен использоваться как операнд унарного оператора*
, который оценивается.