Вызывают ли операторы printf в этом примере неопределенное поведение? - PullRequest
0 голосов
/ 12 декабря 2018

Получено из этого вопроса ...
Учитывая объявление в строке 1 main, являются ли второе и третье printf операторы неопределенным поведением, поскольку ониуказать места, не принадлежащие этому процессу?

struct my_structure {
    int i;
};

void main() {
    struct my_structure variable = {20};
    struct my_structure *p = &variable;

    printf("NUMBER: %d\n", p++->i);  
    printf("NUMBER: %d\n", p++->i);   
    printf("NUMBER: %d\n", p++->i);   
}

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

В этом случае первый printf() в порядке в соответствии с C11 6.5.6.8

printf("NUMBER: %d\n", p++->i);  

2-й p++ равен неопределенное поведение (UB), @ Osiris , так как он пытается сформировать указатель более чем за 1 struct my_structure variable.

Остальная часть кода не имеет значения.

//                     vvv
printf("NUMBER: %d\n", p++->i); 

Подробно: 2-е постинкрементное значение p может иметь место до или может быть отложено до попытки доступа к UB(с предварительным приращением p).Поскольку приращение и доступ - UB, любой ведет к UB.

0 голосов
/ 12 декабря 2018

p сделано так, чтобы оно указывало на элемент, который не отличается от массива из 1 элемента.

То есть, доступ к нескольким последовательным элементам путем увеличения p равен undefinedповедение .

Чтобы быть действительным, вам нужно указать на 3 последовательных элемента, таких как:

struct my_structure variable[3];  // should be initialized too

Чтобы быть полным, p++ сама по себе не является проблемой (указатель указывает на недопустимое местоположение, ну и что? как это происходит после большинства циклов указателя), это тот факт, что мы пытаемся прочитать из памяти при выполнении p->i в недопустимом месте, что является проблемой.

...