Это один из тех странных случаев, когда мы сталкиваемся с ограничениями английского языка и несогласованной структурой в стандарте. Так что в лучшем случае я могу привести убедительный контраргумент, поскольку это невозможно доказать :) 1
Код в вопросе демонстрирует четко определенное поведение.
Поскольку в основе вопроса лежит [7.1.4], давайте начнем с этого:
Каждое из следующих утверждений применяется, если иное явно не указано в подробных описаниях, которые следуют: Если аргумент функции имеет недопустимое значение (например, значение вне домена функции или указатель вне адресное пространство программы, или нулевой указатель, [... другие примеры ...]) [...] поведение не определено. [... другие утверждения ...]
Это корявый язык. Одна интерпретация состоит в том, что элементы в списке являются UB для всех функций библиотеки, если они не отменены отдельными описаниями. Но список начинается с «таких как», что указывает на то, что он иллюстративный, а не исчерпывающий. Например, в нем не упоминается правильное завершение строк нулевым символом (критично для поведения, например, strcpy
).
Таким образом, ясно, что цель / область действия 7.1.4 просто состоит в том, что «недопустимое значение» ведет к UB (, если не указано иное). Мы должны изучить описание каждой функции, чтобы определить, что считается «недопустимым значением».
Пример 1 - strcpy
[7.21.2.3] говорит только следующее:
Функция strcpy
копирует строку, на которую указывает s2
(включая завершающий нулевой символ), в массив, на который указывает s1
. Если копирование происходит между перекрывающимися объектами, поведение не определено.
В нем нет явного упоминания нулевых указателей, но и нет упоминания о нулевых терминаторах. Вместо этого из «строки, на которую указывает s2
» делается вывод, что единственными допустимыми значениями являются строки (т. Е. Указатели на массивы символов с завершающим нулем).
Действительно, эту закономерность можно увидеть в отдельных описаниях. Еще несколько примеров:
Пример 2 - printf
[7.19.6.1] говорит следующее о %p
:
p
- аргумент должен быть указателем на void
. Значение указателя преобразуется в последовательность печатаемых символов способом, определяемым реализацией.
Null - это допустимое значение указателя, и в этом разделе не упоминается явно ни то, что null - это особый случай, ни то, что указатель должен указывать на объект. Таким образом определяется поведение.
1. Если не будет заявлен автор стандартов или если мы не найдем что-то похожее на обоснование, разъясняющий ситуацию.
person
Oliver Charlesworth
schedule
09.07.2017