Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[54.81.185.66] |
|
Сообщ.
#1
,
|
|
|
Собственно сабж.
Есть некий код: void f(char *p, int size) { char* end = &p[size]; } //... char data[] = {'1', '2', '3'}; f(data, sizeof(data)); Есть тут UB или нет? |
Сообщ.
#2
,
|
|
|
В целом – для произвольного size за пределами массива – UB нет, есть неопределённость результата &. Соответственно UB вызовет его использование. Однако относительно one past the last элемента дополнительно позволяется сделать такому указателю -- и получить нормальный указатель на последний элемент. Соответственно и наоборот, сделав ++ указателю на последний элемент, получим указатель на one past the last. Т.о. такой указатель можно считать чётко определённым, что однако не отменяет его невалидности, так что * применять к нему нельзя. (Ещё точнее – можно, нельзя использовать полученное результатом l-value.)
Так что взятие адреса элемента сразу за концом массива само по себе не ведёт к неприятностям. |
Сообщ.
#3
,
|
|
|
Qraizer, спасибо. Я так тоже считаю, просто есть человек, который тыкает в Стандарт и показывает, что a[i] <-> *(a + i).
|
Сообщ.
#4
,
|
|
|
Ну, он правильно тыкает. Есть нюанс: разыменование указателя возвращает l-value на объект (не в терминах ООП) всегда, но это не ведёт к неприятностям само по себе. К неприятностям ведёт работа с объектом там, где его нет, и это совсем отдельный пункт Стандарта. Указатель на one last the past как раз такой указатель: разыменовать можно, но на объект он не указывает. Ты же не работаешь с объектом, ты применяешь к его l-value операцию &, а её описание сформулировано в терминах, наличия объекта не требующих. Её можно применить даже к incomplete type, и при этом её поведение остаётся чётко определённым.
|