Это предложено Вот а также Вот что во избежание предупреждения «форматная строка не является строковым литералом» в Clang, следует использовать следующее __attribute__
раздел кода перед определением функции, чтобы сказать Clang, что одна из функций из printf
семья вызывается внутри функции:
__attribute__((__format__ (__printf__, 3, 0)))
У меня вопрос почему? Я посмотрел на официальную документацию Вот но не могу по-настоящему понять проблему.
Дело в том, что это вообще довольно плохая идея передать произвольный ввод как printf
формат строки Одно несоответствие типов, и вы получили билет в один конец в страну неопределенного поведения (не говоря уже о страшном %n
спецификатор, который может вызвать запись в произвольную память с несовпадением).
По этой причине GCC и Clang будут жаловаться, если вы позвоните printf
с не-литералом (и если вы вызываете его с литеральной строкой формата, они проверят строку формата на соответствие предоставленным аргументам). __attribute__((__format__ (__printf__,...)
сообщает компилятору, что один из ваших параметров printf
форматирует строку и применяет проверку при вызове этой функции. Поскольку компилятор знает, что параметр строки формата будет проверен при вызове вашей функции, он не будет жаловаться на то, что вы используете этот параметр в качестве строки формата внутри своей функции.