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 вообще делает так независимо от присутствия макроса - насколько я знаю. Все могло измениться.

Другие вопросы по тегам