Это встречается повсюду в стандарте, не только в дополнительном интерфейсе проверки границ, но и в обязательных библиотечных функциях, таких как strcpy
. Интерфейсные функции проверки границ просто унаследовали один и тот же текст.
Формальное определение объекта:
3,15
объект
область хранения данных в среде исполнения, содержимое которой может представлять
Значения
Исходя из этого, строка должна быть целым массивом, включая нулевой терминатор. Поскольку такая функция, как strcpy
, прервется, если нулевой терминатор каким-либо образом будет перезаписан во время копирования, ее следует рассматривать как часть объекта (массива).
Кажется, что нет определения термина "перекрытие", но цель довольно ясна: предотвратить ситуации, подобные этой:
char str[] = "foobar";
strcpy(str+3,str);
, где одна из возможных реализаций strcpy
будет while(*dst++ = *src++){}
. Который сломался бы, поскольку он никогда не достигнет нулевого терминатора, и мы закончили бы писать вне границ.
Примечательно, что вы уже обещали компилятору, что параметры не перекрываются, когда вы передаете их функции, ожидающей указателей restrict
. Текст в стандарте, касающийся того, что перекрытия не определены, еще яснее.
В примере strcpy
любой lvalue-доступ к тому, на что указывает dst
, не может изменять то, на что указывает str
, или мы нарушаем определение restrict
(C17 6.7.3) и тем самым вызвать неопределенное поведение.
Насколько я знаю, это всегда ответственность программиста. Ни один из известных мне компиляторов не выдает диагностических сообщений о нарушениях restrict
на стороне вызывающего.