This code compiles even with -Wall -Werror
but it should not:
#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>();
}
If f()
is not a template, GCC and Clang refuse to compile it, as I expect and desire. But as written above, GCC and Clang compile it without any warning.
GCC trunk does refuse to compile it, unlike all the released versions. So does MSVC 19, but I can't use that.
My question is: can you come up with some tweak to the code that will make it fail in at least GCC 8.2 when the format does not match its arguments? Bonus points if it works on recent Clang too.
I can't actually call printf() or even a function of my own with the same signature as printf(), because some of the arguments in my real code come from calls to functions which are expensive to invoke. I want to be able to confirm that printf() or a similar function can accept my arguments without actually invoking any such function.
Demo with template which unexpectedly compiles: https://godbolt.org/z/rWxYob
Demo without template which correctly refuses to compile: https://godbolt.org/z/xb6GYo
You might try:
template <typename T>
void f()
{
if (false) { printf("%u", 1.0); } // format does not match args
}
You might need some additional pragma to silent warning about condition evaluate to always false and or unreachable code.