Ответ 1
В этом случае s
не означает "безопасный", это означает "повышенная безопасность". Для fopen_s
параметры проверяются на достоверность перед попыткой открыть файл.
С помощью fopen
вы можете передать указатель NULL для имени файла, и все, скорее всего, распадется. fopen_s
не имеет такой задачи (a).
Имейте в виду, что эти интерфейсы проверки границ, такие как fopen_s
, являются необязательной частью стандарта ISO, подробно описанной в Приложении K (как и на C11, в любом случае). Реализации не обязаны предоставлять их, и, если честно, fopen
и многие другие так называемые небезопасные функции, совершенно безопасны, если вы знаете, что делаете в качестве кодера.
Интересно отметить, что fopen_s
будет улавливать NULL-указатели для вас, но не недействительные указатели, поэтому почему безопасность повышена, а не безопасна - вы все равно можете нанести какой-то ущерб, если вы передадите недопустимый, но не NULL-указатель.
Другие "безопасные" функции, которые заставляют вас предоставлять размеры буфера назначения, также безопасны только до тех пор, пока вы передаете правильный размер. Передайте что-то слишком большое, и все ставки отключены.
(a) Из C11 K.3.5.2.1 The fopen_s function
:
errno_t fopen_s (
FILE * restrict * restrict streamptr,
const char * restrict filename,
const char * restrict mode);
<сильные > Runtime-ограничения
Ни один из streamptr, filename или mode не должен быть нулевым указателем.
Если есть нарушение ограничения времени выполнения, fopen_s не пытается открыть файл. Кроме того, если streamptr не является нулевым указателем, fopen_s устанавливает * streamptr в нулевой указатель.
Контрастируйте это с помощью C11 7.20.5.3 The fopen function
, в котором указано, что имя файла и режим должны указывать на строку, но не указывать, что произойдет, если вы указали указатель NULL (большинство реализаций, скорее всего, сбой с разыменованием нулевого указателя).