4

On my computer, long takes a maximum value of 9223372036854775807. However, when I tired unsigned long with a larger value the compiler throws a warning saying it needs to be interpreted as an unsigned long when I already had it defined as so. Why is that the case?

//assigning maximum value of a long integer. (No error)
long max_l = 9223372036854775807L;

//assigning an unsigned long integer.
unsigned long max_ul = 9223372036854775808L; //warning: integer literal is too large to be represented in a signed
                                             //integer type, interpreting as unsigned [-Wimplicitly-unsigned-literal]

cc --version
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
2
  • 2
    You can remove the prefix. Commented Sep 10, 2019 at 11:28
  • Note that, assuming the system has 64-bit long and no larger extended integer types, this code behaves differently in C90 than in later editions. In C90 the constant would have type unsigned long even though the suffix is L, whereas since C99 the decimal constant without u can only ever have a signed type (with it being a constraint violation if no suitable type exists). So it is relevant in which mode you are invoking the compiler. Commented Sep 10, 2019 at 11:59

2 Answers 2

14

This integer constant:

9223372036854775808L

is too large to be stored in a long.

Instead, use:

9223372036854775808UL

This specifies that the constant has the type unsigned long by appending the suffix UL

Or just use the suffix U:

unsigned long max_ul = 9223372036854775808U;

When an integer constant has the suffix L (or l) then the compiler determines its type in the following order: the first of the types

signed long
signed long long

in which its value can be represented. It seems that the type signed long has the same integer representation as the type signed long long established by the compiler. So neither the type signed long nor the type signed long long can represent the constant. The constant is too big for these types. But the type unsigned long that has the same internal representation as the type unsigned long long established by the compiler can represent the constant.

Pay also attention to that there are no negative integer constants in C. If for example you will write

int x = -1;

then the compiler splits the construction -1 into two tokens: the integer constant 1 and the unary operator -.

Consider the following demonstrative program

#include <stdio.h>

int main(void) 
{
    int a[] = { 0, 1, 2 };
    int *p = a + 1;

    printf( "p[-1] = %d\n", p[-1] );
    printf( "-1[p] = %d\n", -1[p] );

    return 0;
}

The program output is

p[-1] = 0
-1[p] = -2

The expression -1[p] is not the same as the expression (-1)[p]. It is processed as -(1[p] ) that is equivalent to -p[1].

Sign up to request clarification or add additional context in comments.

1 Comment

Yep. That works. Also note that %lu needs to be used as the formatter to print the correct number.
3

Every integer constant such as 9223372036854775808 has a type of its own. There's some rules for what types the compiler pick for integer constants in your program. For plain decimal constants (without any U, L suffix), it goes like this:

  • Try if it fits inside int.
  • If not, try if it fits inside long.
  • If not, try if it fits inside long long.

(See the table in C17 6.4.4.1 for details)

Apparently all of these checks failed for the value 2^63 on your system, which is to be expected since a signed 64 bit only goes up to 2^63 - 1.

Adding L doesn't solve anything, because that only tells the compiler to do the above checks but start with long.

Declaring the type where you will store the integer constant as unsigned doesn't solve anything, because the type to the left of the assignment/initialization has nothing to do with the type of the integer constant. You could write my_custom_type x = 9223372036854775808L; and you'd get the same warning.

The obvious solution is to to use unsigned suffix U. Otherwise, if you for some reason need >63 value bit signed, you'd need to find some 128 bit signed "big int" library, which would be far more painful.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.