【问题标题】:Why use __attribute__((__format__ (__printf__,...) in Clang to avoid format string is not a string literal?为什么在 Clang 中使用 __attribute__((__format__ (__printf__,...) 来避免格式字符串不是字符串文字?
【发布时间】:2014-11-18 18:00:51
【问题描述】:
建议here 和here 在 Clang 中避免警告“格式字符串不是字符串文字”,应该在函数定义之前使用以下 __attribute__ 代码部分来告诉 Clang来自printf 家族的函数在函数内部被调用:
__attribute__((__format__ (__printf__, 3, 0)))
我的问题是为什么?我查看了官方文档here,但无法真正指出问题所在。
【问题讨论】:
标签:
c++
c
clang
clang-static-analyzer
【解决方案1】:
关键是,将任意输入作为printf 格式字符串传递通常是一个非常坏主意。一种类型不匹配,您就获得了未定义行为领域的单程票(更不用说可怕的 %n 说明符,它可能导致写入不匹配的任意内存)。
因此,如果您使用非文字调用 printf,GCC 和 clang 会抱怨(如果您使用文字格式字符串调用它,它们将根据提供的参数检查格式字符串)。 __attribute__((__format__ (__printf__,...) 告诉编译器您的参数之一是 printf 格式字符串,并导致在调用该函数时应用检查。由于编译器知道在调用函数时会检查格式字符串参数,因此它不会抱怨您将该参数用作函数内部的格式字符串。