views:

609

answers:

5

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).

A: 

Have you tried:

long long a = 2147483647;
highlycaffeinated
Thanks for the prompt response! However that doesn't seem to work, either with or without the -m64 switch.
seandbarrett
+3  A: 

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
I second this.And to print you could use the 'PRI' macros defined in stdint.hprintf("a = %"PRIu64"\n");
joveha
+8  A: 

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
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
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
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
+2  A: 

Use the C99 standard:

#include <stdint.h>

uint64_t a = 2147483647ULL;

There's an excellent C99 library overview at Dinkumware.

Norman Ramsey
A: 

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