在 R/terra 包的 C++ 代码中,我使用以下代码来处理警告:
template <typename... Args>
inline void warningNoCall(const char* fmt, Args&&... args ) {
Rf_warningcall(R_NilValue, tfm::format(fmt, std::forward<Args>(args)... ).c_str());
}
工作正常,但 CRAN 现在要求我修复它,因为 CLANG 编译器警告。
Found the following significant warnings:
RcppFunctions.cpp:298:32: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
./geos_spat.h:80:32: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
See ‘/home/hornik/tmp/R.check/r-devel-clang/Work/PKGS/terra.Rcheck/00install.out’ for details.
这已修复由
compileAttributes()
生成的 Rcpp 代码(请参阅 https://github.com/RcppCore/Rcpp/issues/1287),但这里的情况并非如此。 (这不是由compileAttributes
生成的。)
如何调整上面的代码以避免出现此警告?
正如您可能已经看到首先在相应的 GitHub 问题 #1287 或第二个在这个 SO 问题中或然后在我对 Rcpp 列表的总结答案中,这些来自 R-devel 和
g++
/ 的新警告clang++
下的-Wformat -Wformat-security
已经吸引了一些人。
在大多数情况下这很简单。在你的情况下,它与你的代码约定有点不同,但我认为你想要
template <typename... Args>
inline void warningNoCall(const char* fmt, Args&&... args ) {
Rf_warningcall(R_NilValue, "%s", tfm::format(fmt, std::forward<Args>(args)... ).c_str());
}
将我现在在 Rcpp 本身中拥有的内容与格式字符串作为第二个参数进行匹配:
inline void warningcall(SEXP call, const std::string & s) {
Rf_warningcall(call, "%s", s.c_str());
}
(我想你也可以尝试
template <typename... Args>
inline void warningNoCall(const char* fmt, Args&&... args ) {
::Rf_warning("%s", tfm::format(fmt, std::forward<Args>(args)... ).c_str());
}
如果来电者与您无关。但这未经测试。)