Почему используйте __attribute __ ((__ format__ (__printf __, …) в Clang, чтобы избежать форматирования строки, а не строкового литерала)?

Это предложено Вот а также Вот что во избежание предупреждения «форматная строка не является строковым литералом» в Clang, следует использовать следующее __attribute__ раздел кода перед определением функции, чтобы сказать Clang, что одна из функций из printf семья вызывается внутри функции:

__attribute__((__format__ (__printf__, 3, 0)))

У меня вопрос почему? Я посмотрел на официальную документацию Вот но не могу по-настоящему понять проблему.

2

Решение

Дело в том, что это вообще довольно плохая идея передать произвольный ввод как printf формат строки Одно несоответствие типов, и вы получили билет в один конец в страну неопределенного поведения (не говоря уже о страшном %n спецификатор, который может вызвать запись в произвольную память с несовпадением).

По этой причине GCC и Clang будут жаловаться, если вы позвоните printf с не-литералом (и если вы вызываете его с литеральной строкой формата, они проверят строку формата на соответствие предоставленным аргументам). __attribute__((__format__ (__printf__,...) сообщает компилятору, что один из ваших параметров printf форматирует строку и применяет проверку при вызове этой функции. Поскольку компилятор знает, что параметр строки формата будет проверен при вызове вашей функции, он не будет жаловаться на то, что вы используете этот параметр в качестве строки формата внутри своей функции.

4

Другие решения