Strange error message from an incorrect typedef

David Brown david@westcontrol.com
Tue Sep 24 08:11:00 GMT 2019


On 24/09/2019 07:50, Edward Diener wrote:
> The program is simply:
> 
> typedef int test_line[(0 == 1) ? 1 : -1];
> 
> int main()
>     {
>     return 0;
>     }
> 
> Please do not ask why as this is just an example. 

These kinds of expressions are common as the result of "static
assertion" macros - a very useful technique.  But if you are using C++11
(or C11) onwards, consider moving to native static_assert() to get the
same feature but with clearer error messages.

> If I compile the above
> source as test_typedef.cpp using gcc-9.2 with -m64 and -std=c++11 I
> receive the error messages of:
> 
>  test_typedef.cpp:1:40: error: narrowing conversion of '-1' from 'int'
> to 'long long unsigned int' [-Wnarrowing]
>      1 | typedef int test_line[(0 == 1) ? 1 : -1];
>        |                                        ^
>  test_typedef.cpp:1:32: error: size '-1' of array 'test_line' is negative
>      1 | typedef int test_line[(0 == 1) ? 1 : -1];
>        |                       ~~~~~~~~~^~~~~~~~
> 
> While I am expecting the second error, why am I getting the first error
> ? Why is an array bounds a 'long long unsigned int' and why is
> converting from an 'int' to a 'long long unsigned int' a narrowing
> conversion ?

Array bounds are really of type "size_t", but that is usually the same
as "unsigned long long int" on a 64-bit system.  (On a 32-bit target it
might be "unsigned int".).  The warning is because you are asking to
convert the value -1 to an unsigned type which cannot represent that
value.  While the conversion is fully defined (it gives
0xffffffffffffffff, if I have counted my f's correctly), it is not the
same value - so the compiler is warning you about it.  The warning is
optional, as is turning the warning into an error - it is controlled by
gcc flags.

> 
> If I change the typedef line to:
> 
> typedef int test_line[(1 == 1) ? 1 : -1];
> 
> and compile I do not get an error telling me 'narrowing conversion of
> '1' from 'int' to 'long long unsigned int' [-Wnarrowing]'.
> 

That is because a "long long unsigned int" can hold the value 1.



More information about the Gcc-help mailing list