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

Reply via email to