Безопасные перегрузки шаблонов
Корпорация Майкрософт объявила устаревшими многие функции библиотеки C времени выполнения (CRT), заменив их версиями с более высоким уровнем безопасности. Например, strcpy_s
является более безопасной заменой для strcpy
. Устаревшие функции являются общими источниками ошибок безопасности, так как они не препятствуют операциям, которые могут перезаписать память. По умолчанию компилятор выдает предупреждение об устаревании, если в коде присутствует любая из этих функций. CRT предоставляет для этих функций перегруженные шаблоны C++, которые помогают упростить переход к более безопасным вариантам.
Например, для этого фрагмента кода создается предупреждение, поскольку функция strcpy
объявлена устаревшей:
char szBuf[10];
strcpy(szBuf, "test"); // warning: deprecated
Предупреждение об устаревании сообщает вам, что используемый код может быть небезопасным. Если вы проверили, что код не может перезаписать память, у вас есть несколько вариантов. Вы можете просто игнорировать это предупреждение. Вы можете добавить символ _CRT_SECURE_NO_WARNINGS
перед инструкциями include в заголовках CRT, чтобы подавить предупреждение. Также вы можете изменить код, заменив эту функцию на strcpy_s
:
char szBuf[10];
strcpy_s(szBuf, 10, "test"); // security-enhanced _s function
Перегрузки шаблона предоставляют больше возможностей. Если определить _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
значение 1, он включает перегрузки шаблонов стандартных функций CRT, которые вызывают более безопасные варианты автоматически. Если _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
имеет значение "1", никаких изменений в коде не требуется. Вызов функции strcpy
в фоновом режиме заменяется вызовом функции strcpy_s
с автоматической подстановкой аргумента размера.
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
// ...
char szBuf[10];
strcpy(szBuf, "test"); // ==> strcpy_s(szBuf, 10, "test")
Макрос _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
не влияет на функции, которые принимают число, например strncpy
. Чтобы включить перегруженные шаблоны для функций, принимающих количество, определите _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT
как значение "1". Однако перед этим действием следует убедиться, что код передает количество символов, а не размер буфера (частая ошибка). Кроме того, код, который явно записывает значение NULL в конец буфера после вызова функции, является необязательным, если вызывается безопасный вариант. Если требуется поведение усечения, см. раздел _TRUNCATE
.
Примечание.
Макрос _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT
требует, чтобы _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
также был определен как значение "1". Если _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT
определен как значение "1" и _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
определен как значение "0", в приложении не выполняются никакие перегрузки шаблонов.
Если вы определите _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES
со значением "1", включается перегрузка шаблонов безопасными вариантами (имена которых оканчиваются на "_s"). В этом случае, если _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES
определен как значение "1", в исходном коде необходимо сделать одно небольшое изменение.
#define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1
// ...
char szBuf[10];
strcpy_s(szBuf, "test"); // ==> strcpy_s(szBuf, 10, "test")
Требуется изменить только имена функций (добавив к ним символы "_s"), а перегрузка шаблона автоматически подставит аргумент размера.
По умолчанию _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
и _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT
определены как "0" (запрещено), а _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES
определен как "1" (разрешено).
Перегрузки шаблона работают только для статических массивов. Динамически выделенные буферы требуют других изменений исходного кода. В приведенных выше примерах:
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
// ...
char *szBuf = (char*)malloc(10);
strcpy(szBuf, "test"); // still deprecated; change it to
// strcpy_s(szBuf, 10, "test");
И в этом примере:
#define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1
// ...
char *szBuf = (char*)malloc(10);
strcpy_s(szBuf, "test"); // doesn't compile; change it to
// strcpy_s(szBuf, 10, "test");
См. также
Функции безопасности в CRT
Файлы среды выполнения C (CRT) и стандартной библиотеки C++ (STL) .lib