Making 'long' 4 bytes in gcc on a 64-bit L

2019-02-16 15:09发布

问题:

I am working on porting an application to 64-bit on Linux platform. The application is currently supported on Linux, Windows, Mac 32-bit and Windows 64-bit. One of the issues we are frequently encountering is the usage of long for int and vice versa. This wasn't a problem till now since long and int are interchangeable (both are 4 bytes) in the platforms the application is currently supported on. The codebase being a huge one, with lots of legacy code with #defines for many data types, makes it cumbersome to search all usage of long and replace appropriately with int.

  1. As a short term solution, is there a way to make GCC use 4 bytes instead of 8 for 'long'?
  2. If it has, what are issues that we might face? If not, is there an easier way to fix the long and int problem?

回答1:

  1. No. On Linux x86_64 the ABI specifies that long is a 8 byte type (LP64). In fact, most if not all 64-bit Unix systems (including 64-bit OS X, AFAIK) are LP64 so this is nothing specific to Linux.

  2. Beyond fixing your code, no.

If you need a portable integer type which is large enough to store a pointer value, use intptr_t or uintptr_t (but usually wanting to store a pointer value into an integer means that you're doing something wrong, so think twice!). For an integer type which is capable of representing the difference between two pointers, use ptrdiff_t. For sizes of objects, use size_t.



回答2:

-m32 generates 32-bit code.

-mx32 generates 64-bit code but uses 32-bit longs and pointers.

Intel 386 and AMD x86-64 Options



回答3:

It depends on what you mean by "porting to 64 bit".

  1. You simply want your application to work on a 64-bits linux: you can compile it in 32-bits and it will run in compatibility mode on most distributions which provides the 32-bits libraries. For this you must use a 32 bits version of gcc (e.g. package gcc:i386 on Ubuntu), or use the -m32 flag with the native gcc version.

  2. You want to benefit from the long mode of your processor (aka x86_64 architecture) but still use most 32-bits C conventions (including long int on 4 bytes): you can use the x32 ABI by using the -mx32 flag of gcc, which requires that your distribution allows it (support must be enable in your kernel and specific libraries are needed e.g. in /libx32). I am using Ubuntu 16.04 and this mode is working perfectly fine, except that there is much fewer precompiled libraries available.

  3. You want to exactly use the x86_64 architecture and ABI, but with 4 bytes long: this is impossible as the x86_64 ABI requires the long to be 8 bytes.