GCC 和 Clang printf 格式检查不适用于模板函数中的 decltype
GCC and Clang printf format check doesn't work with decltype in a template function
此代码即使使用 -Wall -Werror
也能编译,但它不应该:
#include <cstdio>
template <typename T>
void f()
{
decltype(printf("%u", 1.0))* p = nullptr; // format does not match args
(void)p;
}
void g()
{
f<int>();
}
如果 f()
不是模板,GCC 和 Clang 将拒绝编译它,正如我所期望的那样。但是如上所述,GCC 和 Clang 编译它时没有任何警告。
GCC trunk 确实拒绝编译它,这与所有已发布的版本不同。 MSVC 19 也是,但我不能使用它。
我的问题是:当格式与其参数不匹配时,您能否对代码进行一些调整,使其至少在 GCC 8.2 中失败? 加分如果它也适用于最近的 Clang。
我实际上不能调用 printf() 甚至我自己的具有与 printf() 相同签名的函数,因为我的真实代码中的一些参数来自对函数的调用,这些函数的调用成本很高。我希望能够确认 printf() 或类似函数可以在不实际调用任何此类函数的情况下接受我的参数。
带有意外编译的模板的演示:https://godbolt.org/z/rWxYob
没有正确拒绝编译的模板的演示:https://godbolt.org/z/xb6GYo
你可以试试:
template <typename T>
void f()
{
if (false) { printf("%u", 1.0); } // format does not match args
}
您可能需要一些额外的 pragma 来静默警告有关条件评估始终为 false 和/或无法访问的代码。
此代码即使使用 -Wall -Werror
也能编译,但它不应该:
#include <cstdio>
template <typename T>
void f()
{
decltype(printf("%u", 1.0))* p = nullptr; // format does not match args
(void)p;
}
void g()
{
f<int>();
}
如果 f()
不是模板,GCC 和 Clang 将拒绝编译它,正如我所期望的那样。但是如上所述,GCC 和 Clang 编译它时没有任何警告。
GCC trunk 确实拒绝编译它,这与所有已发布的版本不同。 MSVC 19 也是,但我不能使用它。
我的问题是:当格式与其参数不匹配时,您能否对代码进行一些调整,使其至少在 GCC 8.2 中失败? 加分如果它也适用于最近的 Clang。
我实际上不能调用 printf() 甚至我自己的具有与 printf() 相同签名的函数,因为我的真实代码中的一些参数来自对函数的调用,这些函数的调用成本很高。我希望能够确认 printf() 或类似函数可以在不实际调用任何此类函数的情况下接受我的参数。
带有意外编译的模板的演示:https://godbolt.org/z/rWxYob
没有正确拒绝编译的模板的演示:https://godbolt.org/z/xb6GYo
你可以试试:
template <typename T>
void f()
{
if (false) { printf("%u", 1.0); } // format does not match args
}
您可能需要一些额外的 pragma 来静默警告有关条件评估始终为 false 和/或无法访问的代码。