1

I am trying to force 64 bit long integers on OS X 10.5.6. running on an Apple MacBook Intel Core 2 Duo. Here is my c code:

#include<stdio.h>

int main()
{
    long a = 2147483647; /*== 2^32 - 1*/
    long aplus1;

    printf("a== %d. sizeof(a) == %d  \n", a, sizeof(a));

    aplus1 = a+1;

    printf("aplus1 = %d \n", aplus1);
}

Compiling without any switches yields the following:

$ gcc testlong.c -o testlong ;./testlong

a== 2147483647. sizeof(a) == 4  
aplus1 = -2147483648 

Compiling with the -m64 switch yields:

$ gcc testlong.c -o testlong -m64; ./testlong

a== 2147483647. sizeof(a) == 8  
aplus1 = -2147483648 

So the second version is apparently using 64 bit storage, but still generates the overflow error, although 2^32 should be well within the range of a 64 bit integer. Any ideas?

I would prefer a solution that can be forced from a gcc option rather than requiring me to change multiple lines of source code (my actual problem is not the above example specifically, rather I need to force long integer arithmetic in a more general situation).

ChrisF
  • 134,786
  • 31
  • 255
  • 325
seandbarrett
  • 11
  • 1
  • 3

5 Answers5

9

Not only do you have to use long long, but you must also change the printf() statements accordingly.

#include<stdio.h>

int main()
{
    long long a = 2147483647; /*== 2^32 - 1*/
    long long aplus1;

    printf("a== %lld. sizeof(a) == %d  \n", a, sizeof(a));

    aplus1 = a+1;

    printf("aplus1 = %lld \n", aplus1);
}

%lld is the code for long longs.

Apparently true 64-bit programs can use %d for 64-bit integers - I don't know if it's possible to configure it to compile in this mode.

v3.
  • 2,003
  • 15
  • 18
  • 1
    Indeed, the printf format specification is the problem. If OP's system has 32-bit ints and 64-bit longs, `long long` isn't necessary -- just changing the format to "%ld" should be sufficient. – ephemient Apr 28 '09 at 21:39
  • Ok yes, ephemient is exactly right. It seems the problem in my original code was in the printf statement - changing to %ld fixes the problem without needing "long long"s, provided I compile with the -m64 switch. Thanks! – seandbarrett Apr 28 '09 at 21:49
  • 6
    Mac OS X 64-bit follows the LP64 model, which is (int=32,long=longlong=pointer=64); this is the most common 64-bit model. Win64 uses LLP64(int=long=32,longlong=pointer=64). ICC accepts `-DMKL_ILP64` to follow the ILP64 model (int=long=longlong=pointer=64), and GCC has `-mint64` for the same, but it's not available on most platforms and breaks compatibility with other libraries and system APIs. – ephemient Apr 28 '09 at 21:54
3

If you are using C99, include stdint.h and use uint64_t and int64_t. Other than that, unsigned long long a = 0x100000000ull; should work too.

D.Shawley
  • 58,213
  • 10
  • 98
  • 113
  • I second this. And to print you could use the 'PRI' macros defined in stdint.h printf("a = %"PRIu64"\n"); – joveha Apr 29 '09 at 21:19
2

Use the C99 standard:

#include <stdint.h>

uint64_t a = 2147483647ULL;

There's an excellent C99 library overview at Dinkumware.

Norman Ramsey
  • 198,648
  • 61
  • 360
  • 533
0

Have you tried:

long long a = 2147483647;
highlycaffeinated
  • 19,729
  • 9
  • 60
  • 91
0

The literal 2147483647 in C code is of type int. If you want it to be a long, it doesn't help to have a long on the left-hand side, it's still an int on the right.

Make it a long literal, by appending a 'L': 2147483647L (upper-case is recommended, lower-case 'l' works too but can be very confusing depending on the font).

unwind
  • 391,730
  • 64
  • 469
  • 606