Из-за того, как работают вариативные аргументы C, компилятор не может отслеживать их правильное использование. По-прежнему (синтаксически) законно предоставлять меньше или больше параметров, необходимых для работы функции, хотя обычно это приводит к неопределенному поведению при взгляде на стандарт.
Объявление printf
выглядит так:
int printf(const char*, ...);
Компилятор видит только ...
и знает, что может быть ноль или более дополнительных аргументов, которые функция может использовать или не использовать. Вызванная функция не знает, сколько аргументов ей передано; в лучшем случае он может предполагать, что ему была передана вся необходимая информация и ничего более.
Сравните это с другими языками, такими как C#:
void WriteLine(string format, params object[] arguments);
Здесь метод точно знает, сколько дополнительных аргументов было передано (выполняется arguments.Length
).
В C функции с переменным числом аргументов и особенно printf
являются частой причиной уязвимостей безопасности. Printf
заканчивается чтением необработанных байтов из стека, что может привести к утечке важной информации о вашем приложении и его среде безопасности.
По этой причине Clang и GCC поддерживают специальное расширение для проверки форматов printf
. Если вы используете недопустимую строку формата, вы получите предупреждение (не ошибку).
code.c:4:11: warning: more '%' conversions than data arguments [-Wformat]
printf("%d\n");
~~^
person
zneak
schedule
28.01.2015