【发布时间】:2014-07-23 07:11:40
【问题描述】:
我正在尝试将 gcc 的 printf 格式字符串的编译时检查与 c++11 的 可变参数模板包结合起来。
我知道我可以使用 gcc 的 __attribute__((format(__printf__, ...)) 装饰器来装饰可变参数函数。
我知道我可以将可变参数模板包扩展为可变参数函数。例如:printf(fmt, pack...);
两者可以结合吗?
在this question 中,接受的答案指出 gcc 需要 literals 才能进行格式检查。
在下面的示例中,const char array 被同时传递给可变参数函数和可变参数函数模板。当在main 中调用check 时,gcc 可以判断它是一个文字,但不是来自check_t
有什么方法可以将fmt 字符串传递给check_t,以使gcc 将其视为文字?
我正在努力实现的工作示例:
#include <iostream>
void check(const char*, ...) __attribute__((format(__printf__, 1, 2)));
void check(const char*, ...)
{
// exists only for the purposes of catching bogus format strings
}
template<typename... Ts>
void check_t(const char fmt[], Ts... ts)
{
// check the format string by expanding ts into the check function
check(fmt, ts...);
}
int main()
{
const char f[] = "foo %s";
check_t(f, 5); // compiles
check(f, 5); // fails to compile
return 0;
}
【问题讨论】:
-
当格式字符串不是编译时常量时会发生什么?
-
据我所知,您无法将字符串文字与字符数组区分开来。
-
@KonradRudolph - gcc 的 printf 格式检查不起作用 - 一直都是这样
-
@KerrekSB 我想你的意思是“常量字符数组”