GCC 和 Clang printf 格式检查不适用于模板函数中的 decltype

问题描述

代码即使使用 -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 主干确实拒绝编译它。 MSVC 19 也是如此,但我不能使用它。

我的问题是:当格式与其参数不匹配时,您能否对代码进行一些调整,使其至少在 GCC 8.2 中失败?如果它适用于最近的也是叮当声。

我实际上无法调用 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 来静默警告有关条件评估为始终错误和/或无法访问的代码。