C++:vsprintf 的安全使用
C++: safe usage of vsprintf
我有一个较大的代码库可以执行 log_msg("Here comes %s", "the text")
,其中 log_message
是一个将函数名称和行号添加到日志消息的宏。
GCC/G++ 当格式字符串与提供的参数不匹配时发出错误警告。不幸的是,有时代码会调用 log_msg(get_the_text())
。 get_the_text()
的 return 值在编译时是未知的,因此如果它包含一些 printf
格式化序列,代码将完全失败。
我正在寻找的是一种通过不解释格式代码的不同代码路径来路由单个参数用法的方法。我尝试了这样的事情,希望非可变情况比可变情况更具体:
void log_the_message_implementation(const char *filename, const char *funcname, const char *msg);
void log_the_message_implementation(const char *filename, const char *funcname, const char *msg, ...);
我希望编译器在没有可变参数时选择单参数函数,但它抱怨调用不明确。
关于如何在不更改来自
log_msg(get_the_text())
到 log_msg("%s", get_the_text())
?
感谢@SamVarshavchik,这就是我想出的:
#include <iostream>
#include <cstdio>
#include <tuple>
template<typename ... Args>
void log(Args ... args) {
if (sizeof...(args) == 1) {
auto t = std::make_tuple(args...);
std::puts(std::get<0>(t));
} else {
std::printf(args...);
}
}
int
main() {
log("Test %d");
log("%s %d\n", "Test", 1);
log([]{ return "%s";}());
return 0;
}
我有一个较大的代码库可以执行 log_msg("Here comes %s", "the text")
,其中 log_message
是一个将函数名称和行号添加到日志消息的宏。
GCC/G++ 当格式字符串与提供的参数不匹配时发出错误警告。不幸的是,有时代码会调用 log_msg(get_the_text())
。 get_the_text()
的 return 值在编译时是未知的,因此如果它包含一些 printf
格式化序列,代码将完全失败。
我正在寻找的是一种通过不解释格式代码的不同代码路径来路由单个参数用法的方法。我尝试了这样的事情,希望非可变情况比可变情况更具体:
void log_the_message_implementation(const char *filename, const char *funcname, const char *msg);
void log_the_message_implementation(const char *filename, const char *funcname, const char *msg, ...);
我希望编译器在没有可变参数时选择单参数函数,但它抱怨调用不明确。
关于如何在不更改来自
log_msg(get_the_text())
到 log_msg("%s", get_the_text())
?
感谢@SamVarshavchik,这就是我想出的:
#include <iostream>
#include <cstdio>
#include <tuple>
template<typename ... Args>
void log(Args ... args) {
if (sizeof...(args) == 1) {
auto t = std::make_tuple(args...);
std::puts(std::get<0>(t));
} else {
std::printf(args...);
}
}
int
main() {
log("Test %d");
log("%s %d\n", "Test", 1);
log([]{ return "%s";}());
return 0;
}