如何在 Clang 中将特定函数参数标记为安全格式字符串?

How to mark a particular function argument as a safe format string in Clang?

我有这样的东西:

static void
my_varargs_internal (const char *prefix, const char *format, va_list args)
{
    printf ("%s: ", prefix);
    vprintf (format, args);
    /* Other more complicated stuff which is why I want this to be a separate function */
    printf ("\n");
}

void
__attribute__ ((format (printf, 1, 2)))
varargs_general (const char *format, ...)
{
    va_list args;
    va_start (args, format);
    my_varargs_internal ("General", format, args);
    va_end (args);
}

void
__attribute__ ((format (printf, 2, 3)))
varargs_specialized (const char *prefix, const char *format, ...)
{
    va_list args;
    va_start (args, format);
    my_varargs_internal (prefix, format, args);
    va_end (args);
}

使用带有 -Wformat -Wformat-nonliteral 的 Clang 进行编译,我在 vprintf 行收到 "Format string is not a string literal" 警告。有没有办法将 format 参数标记为已检查的格式字符串,因为编译器已经在调用 varargs_generalvarargs_specialized 时检查了它?我不能用 format 属性来做到这一点,因为它只适用于可变参数函数,不适用于带有 va_list 参数的函数。

GCC 似乎正确地理解了这种情况并且没有发出警告。

我能够使用以下方式抑制警告:

static void
__attribute__ ((format (printf, 2, 0)))
my_varargs_internal (const char *prefix, const char *format, va_list args)
{
    printf ("%s: ", prefix);
    vprintf (format, args);
    /* Other more complicated stuff which is why I want this to be a separate function */
    printf ("\n");
}

基于Declaring Attributes of Functions:

For functions where the arguments are not available to be checked (such as vprintf), specify the third parameter as zero.