Reputation: 337
I'm encountering an issue where a template function uses std::invoke
to call another function, passing a size_t
argument to a parameter expecting an int32_t
. This should, theoretically, trigger a warning about type conversion. However, when compiling with GCC or Clang using the -Wconversion
flag, no warning is issued, whereas MSVC correctly reports a warning.
Here's a simplified version of the code:
void expectsInt32(int32_t) {
/* … */
}
template<typename Func, typename Arg>
void call(Func func, Arg arg) {
std::invoke(func, arg); // arg is size_t, potentially causing narrowing conversion
}
int main() {
size_t largeNumber = 4294967295; // Maximum value for uint32_t
call(expectsInt32, largeNumber); // Compiles without warning in GCC/Clang with -Wconversion
return 0;
}
On MSVC, this code triggers a warning about the potential data loss during the conversion from size_t to int32_t:
C:/data/msvc/14.39.33321-Pre/include\type_traits(1739): error C2220: the following warning is treated as an error
C:/data/msvc/14.39.33321-Pre/include\type_traits(1739): warning C4267: 'argument': conversion from 'size_t' to 'int32_t', possible loss of data
C:/data/msvc/14.39.33321-Pre/include\type_traits(1739): note: the template instantiation context (the oldest one first) is
<source>(18): note: see reference to function template instantiation 'void call<void(__cdecl *)(int32_t),size_t>(Func,Arg)' being compiled
with
[
Func=void (__cdecl *)(int32_t),
Arg=size_t
]
<source>(12): note: see reference to function template instantiation 'void std::invoke<void(__cdecl *&)(int32_t),Arg&,>(_Callable,_Ty1) noexcept(false)' being compiled
with
[
Arg=size_t,
_Callable=void (__cdecl *&)(int32_t),
_Ty1=size_t &
]
Compiler returned: 2
However, the same warning is not emitted by GCC or Clang, even with the -Wconversion
flag enabled.
Why might GCC/Clang not warn about this implicit conversion in the context of std::invoke
with template arguments? Is there a way to enforce such warnings or add static assertions to catch these cases at compile time?
Here's the code reproduced on Compiler Explorer: https://godbolt.org/z/KPPYM8cna
Upvotes: 3
Views: 160
Reputation: 1
Is there a way to enforce such warnings
Yes, with gcc you can use flag -Wsystem-headers
along with -Wconversion
to enable such warnings. Demo
The warnings are suppressed here because they happen in a system header.
There is a confirmed gcc bug for the same:
Warnings should not be disabled when instantiating templates defined in system headers
Upvotes: 0