2

I have this piece of code

#include <stdio.h>

typedef signed long long v2signed_long 
      __attribute__ ((__vector_size__ (sizeof(signed long long) * 2)));

int main()
{
        v2signed_long v = {4611686018427387904LL, -9223372036854775808LL};

        printf("%lli, %lli\n", v[0], v[1]);
        return 0;
}

Which gives the following warning(The related questions didn't help):

:7:45: warning: integer literal is too large to be represented in
       a signed integer type, interpreting as unsigned
  [-Wimplicitly-unsigned-literal]
    v2signed_long v = {4611686018427387904LL, -9223372036854775808LL};

Is there a way to solve this warning? Thanks!

H.S.
  • 11,654
  • 2
  • 15
  • 32
yonutix
  • 1,964
  • 1
  • 22
  • 51
  • Without really checking the values I suppose @Eljay is correct. The (to me) surprising background is that `-1` is not an integer literal but a constant expression, consisting of the integer literal `1` and the unary minus operator which reverses, as one would expect, the sign. Now, the positive integer literal `9223372036854775808` (to which later the unary minus is applied) is indeed one too large for the long long value space, and the solution is exactly what Eljay said: Use the largest positive integer, reverse its sign, and subtract one. Still a compile time expression, so no harm done. – Peter - Reinstate Monica Feb 20 '20 at 15:31
  • 1
    Does this answer your question? [Why does the most negative int value cause an error about ambiguous function overloads?](https://stackoverflow.com/questions/45469214/why-does-the-most-negative-int-value-cause-an-error-about-ambiguous-function-ove) – NathanOliver Feb 20 '20 at 15:32
  • C is such an evil language. _Of course_ `-9223372036854775808LL` is a positive number, hence the `-` :) Or you could port this on a 1's complement computer, that would solve the problem too :) – Lundin Feb 20 '20 at 15:48
  • 1
    Yet another solution: `(int64_t) -0x8000000000000000`. When C turns evil, respond in the same manner! – Lundin Feb 20 '20 at 15:59

2 Answers2

11

The problem is that -9223372036854775808LL is not actually an integer literal. It's the literal 9223372036854775808LL with the unary - operator applied to it. The value 9223372036854775808 is too large to fit in a signed long long which is why you're getting the warning.

You can fix this by using the expression -9223372036854775807LL - 1LL instead. The value 9223372036854775807 fits in a signed long long as does -9223372036854775807LL, then subtracting 1 gives you the value you want.

Alternately, you can use the macro LLONG_MIN.

dbush
  • 205,898
  • 23
  • 218
  • 273
3

The compiler considers this construction

-9223372036854775808LL

like an integer literal 9223372036854775808LL for which the unary operator - is applied. But the value 9223372036854775808 is too big to be stored in an object of the type signed long long. So the compiler issues an error.

Instead use

#include <limits>

//...

v2signed_long v = 
{
    std::numeric_limits<long long>::max(), std::numeric_limits<long long>::min()
};

Here is a demonstrative program

#include <iostream>
#include <limits>
#include <vector>

int main() 
{
    std::vector<long long> v =
    {
        std::numeric_limits<long long>::max(), std::numeric_limits<long long>::min()
    };

    for ( const auto &item : v ) std::cout << item << '\n';

    return 0;
}

Its output is

9223372036854775807
-9223372036854775808

As you removed the C++ tag then in C the code can look like

#include <stdio.h>
#include <limits.h>

int main(void) 
{
    long long int a[] = { LLONG_MAX, LLONG_MIN };

    printf( "%lld\n%lld\n", a[0], a[1] );

    return 0;
}

The program output is the same as shown above.

In any case it is much better to use this approach instead of magic numbers with a trick that only confuse readers of the code.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335