https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120760
Bug ID: 120760 Summary: Deducing array bound with a small unsigned integral type silently overflows Product: gcc Version: 16.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: mital at mitalashok dot co.uk Target Milestone: --- The following fails to compile with `-std=c++11 -fsyntax-only` <https://godbolt.org/z/E9ffPfTev> (You can make a version that fails in C++98 too): template<long long Val, long long X> struct hard_error_on { static_assert(X != Val, ""); using type = void; }; template<bool i> typename hard_error_on<false, i>::type f1(int(&)[i]); void f1(...); template<unsigned char i> typename hard_error_on<1, i>::type f2(int(&)[i]); void f2(...); int main() { int a[2]; int b[257]; f1(a); f2(b); } It fails both static_asserts, showing it tries to instantiate f1<false> and f2<1>. If the type is signed, it ends up working because signed overflow isn't a constant expression. It makes no sense to deduce `0` and `1` as the sizes of `int[2]` and `int[257]` respectively. <https://wg21.link/temp.deduct#footnote-120> also explicitly says: > 120) Although the template-argument corresponding to a template parameter of > type bool can be deduced from an array bound, the resulting value will always > be true because the array bound will be nonzero. But GCC gives `false` to the constant parameter