sprintf_s() предупреждение о неявном объявлении
У меня есть код C, в котором у меня есть эта строка.
sprintf_s(var, outfile_ppm, local_filecounter++);
Вот, var
является char*
тип и local_filecounter
является int
тип.
Когда я запускаю код, он дает мне это предупреждение:
предупреждение: неявное объявление функции sprintf_s недопустимо в C99 [-Wimplicit-function-объявление]
Что это за предупреждение и как я могу от него избавиться?
1 ответ
sprintf_s
Функция является частью приложения K / TR 24731 границы проверки интерфейсов. Тем не менее, всем, кто интересуется этими интерфейсами, следует ознакомиться с полевым опытом N1967 с Приложением K - Проверка границ интерфейсов. Вот выдержка:
Несмотря на то, что прошло более десяти лет с момента первоначального предложения и почти десять лет с момента ратификации ИСО / МЭК TR 24731-1:2007, а также почти пять лет с момента введения интерфейсов проверки границ в стандарт С, не было реализовано приемлемых соответствующих реализаций., API продолжают вызывать споры, и исполнители продолжают отклонять запросы на реализацию.
Действительно, если вы посмотрите на страницу состояния GCC C11, вы увидите (выделение добавлено):
Проверка границ (Приложение K) [Необязательно]: выпуск библиотеки (не реализовано)
Единственная крупная реализация Приложения K (sprintf_s
и другие подобные _s
версии функций) есть в Visual Studio. Это популярное объяснение состоит в том, что эти функции используются Microsoft для внутреннего использования в собственной кодовой базе для решения проблем безопасности.
Другие реализации полагаются на такие инструменты, как Valgrind, mudflap, sanitizer адресов и т. Д., Чтобы решить тот же набор проблем, и лишь немногие базы кода за пределами Microsoft фактически используют эти функции, поэтому у них очень мало мотивации для их реализации.
Другими словами, если вы не используете Visual Studio, вы не можете использовать эти функции. К счастью, они не нужны.
Вызов sprintf_s
в вопросе весьма подозрительно начать с…
// Wait, what? Something smells fishy...
sprintf_s(var, outfile_ppm, local_filecounter++);
Третий аргумент sprintf_s
должна быть строкой формата, но local_filecounter++
выглядит слишком подозрительно, чтобы быть строкой формата.
Как правило, вы бы использовали snprintf
, который усекает свой вывод до размера буфера, или asprintf
если вы в порядке, используя функции за пределами стандарта C.
char var[256];
snprintf(var, sizeof(var), outfile_ppm, localfile_counter++);
Обратите внимание, что если var
не имеет типа массива, который вы не можете использовать sizeof(var)
чтобы вычислить его размер, и здесь применяются обычные предостережения относительно массивов, распадающихся на указатели при использовании в качестве аргументов функции.
Резюме: вы не можете использовать sprintf_s()
если вы не переключитесь на Visual Studio или не внедрите его самостоятельно. Жесткие печенья
Незначительное примечание: теоретически вы должны определить __STDC_WANT_LIB_EXT1__
если ты хочешь sprintf_s
, На практике, однако, единственная крупная реализация, которая определяет sprintf_s
вообще делает так независимо от присутствия макроса - насколько я знаю. Все могло измениться.