https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69905
TC <rs2740 at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |rs2740 at gmail dot com --- Comment #4 from TC <rs2740 at gmail dot com> --- > template<unsigned _Base, unsigned long long _Pow, char _Dig, char... _Digs> > struct _Number_help > { > using __digit = _Digit<_Base, _Dig>; > using __valid_digit = typename __digit::__valid; > using __next = _Number_help<_Base, > __valid_digit::value ? _Pow / _Base : _Pow, > _Digs...>; > using type = __ull_constant<_Pow * __digit::value + __next::type::value>; > static_assert((type::value / _Pow) == __digit::value, > "integer literal does not fit in unsigned long long"); > }; The issue is that when __valid_digit is false_type (i.e., we have a digit separator), the static_assert check should not be done. In this case, __next is computed using the same _Pow, and __digit::value is zero, which means that it currently fires whenever the next digit is nonzero. I think the fix is simply static_assert(!__valid_digit::value || (type::value / _Pow) == __digit::value, "integer literal does not fit in unsigned long long");