gpt4 book ai didi

c++ - 将零参数包传递给 printf

转载 作者:可可西里 更新时间:2023-11-01 15:54:52 28 4
gpt4 key购买 nike

我创建了一个具有可变参数模板方法的类。此方法调用 printf 函数。将零参数传递给该方法时,我收到 gcc 的编译警告:

warning: format not a string literal and no format arguments [-Wformat-security]

一个简化的类示例是:

class printer{
std::map<int,std::string> str;
public:
printer(){
str[0] = "null\n";
str[1] = "%4d\n";
str[2] = "%4d %4d\n";
str[3] = "%4d %4d\n%4d\n";
}
template<typename ...Args>
void print(Args... args){
printf(str[sizeof...(args)].c_str(),args...);
}
};

使用时

printer p;
p.print(23);
p.print(345,23);

一切顺利编译,但在使用时

printer p;
p.print();

我收到编译警告

main.cpp: In instantiation of ‘void printer::print(Args ...) [with Args = {}]’:
main.cpp:23:11: required from here
main.cpp:17:50: warning: format not a string literal and no format arguments [-Wformat-security]
printf(str[sizeof...(args)].c_str(),args...);

当然如果我只是打电话

printf("null\n");

没有出现警告。

有人可以解释为什么会这样吗?

我可以在不禁用 -Wformat-security 标志的情况下删除警告吗?

最佳答案

如果我们查看 -Wformat-security 的文档,这是一个预期的警告它说:

-Wformat-security If -Wformat is specified, also warn about uses of format functions that represent possible security problems. At present, this warns about calls to printf and scanf functions where the format string is not a string literal and there are no format arguments, as in printf (foo);. This may be a security hole if the format string came from untrusted input and contains `%n'. (This is currently a subset of what -Wformat-nonliteral warns about, but in future warnings may be added to -Wformat-security that are not included in -Wformat-nonliteral.) -Wformat=2

当您不传递参数时就是这种情况,因为 c_str() 的结果不是字符串文字

这个案例:

printf("null\n");

不发出警告,因为 "null\n" 是一个不可能从用户输入的字符串文字。

我们可以从这个 %n format specifier program giving different outputs on different compilers. Why? 看出为什么这是一个潜在的安全问题.

如果你不想要所有的-Wformat-secrity,看起来你必须打开特定的开关:

-Wformat is included in -Wall. For more control over some aspects of format checking, the options -Wformat-y2k, -Wno-format-extra-args, -Wno-format-zero-length, -Wformat-nonliteral, -Wformat-security, and -Wformat=2 are available, but are not included in -Wall.

虽然如果 -Wformat-secrity 稍后添加更多选项,这是一个糟糕的选项,那么您需要不断更新。

AndyG 提到的另一种选择是重载:

void print(){
std::printf("null\n");
}

关于c++ - 将零参数包传递给 printf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29349837/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com