#ifdef for 32-bit platform

29,551

Solution 1

I'm not sure if there is a universal #if def that is appropriate. The C++ standard almost certainly does not define one. There are certainly platform spcefic ones though.

For example, Windows

#if _WIN64 
// 64 bit build
#else
// 32 bit build
#endif

EDIT OP mentioned this is a cross compile between Windows and Non-Windows using GCC and other compilers

There is no universal macro that can be used for all platforms and compilers. A little bit of preprocessor magic though can do the trick. Assuming you're only working on x86 and amd64 chips the following should do the trick. It can easily be expanded for other platforms though

#if _WIN64 || __amd64__
#define PORTABLE_64_BIT
#else
#define PORTABLE_32_BIT
#endif

Solution 2

I recommend bookmarking the predef SourceForge. There's no one answer, but it can certainly help you get started.

EDIT: For GCC-only code, you can use __i386__ to check for 32-bit x86 chips, and I suggest trying __X86_64__ or something similar to check for 64-bit x86 chips. (Note: It has come to my attention that the previous answer involving __ia86__ is actually a different chip, not a 64-bit x86 chip. This just shows my lack of hardware experience. For those more knowledgeable about hardware than I, consule the SourceForge page on predefined macros that I link to above. It's much more accurate than I am.) There are some other ones that would work, but those two should be fairly universal amongs GCC versions.

Solution 3

I would test it indirectly, via the maximum pointer value constant:

#include <stdint.h>

#if UINTPTR_MAX == 0xffFFffFF
// 32-bit platform
#elif UINTPTR_MAX == 0xffFFffFFffFFffFF
// 64-bit platform
#else
#error Unknown platform - does not look either like 32-bit or 64-bit
#endif

This way you don't rely on any platform-specific define for architecture, but on the direct consequence of having a specific architecture - the pointer size.

Solution 4

Have a look at that:

i386 macros
AMD64 macros

Solution 5

You could check a well known type for it's size e.g. sizeof(int*) == 4 for a 32 bit platform.

As sizeof is known at compiletime I believe a

if(sizeof(int*) == 4)
{
  ...
}

should do the trick

Edit: the comments are right, you need to use a regular if, #if won't work.

If you are using C++ You could create templated code and let the compiler choose the specialization for you based on the sizeof() call. If you build for a 32 bit platform the compiler would only instantiate the code for the 32 bit platform. If you build for a 654 bit platform the compiler would only instantiate the code for the 64 bit platform.

Share:
29,551

Related videos on Youtube

veefu
Author by

veefu

Updated on July 09, 2022

Comments

  • veefu
    veefu almost 2 years

    In an application I maintain, we've encountered a problem with file descriptor limitations affecting the stdlib. This problem only affects the 32-bit version of the standard lib.

    I have devised a fix for my code and would like to implement it, but only when compiling for 32-bit executable. What pre-processor symbol can I #ifdef for to determine whether the code is being compiled for a 32 or 64-bit target?

    EDIT

    Sorry, didn't mention, the code is cross-platform, linux, windows, solaris and a few other unix flavors, mostly using GCC for compilation. Any de-facto standards I can use cross-platform?

    EDIT 2

    I've found some definitions "__ILP23" and "__LP64" that seem like they may work... a discussion here explains the background on the unix platform. Anyone had any experience with using these defines? Is this going to be usable?

    • josesuero
      josesuero about 15 years
      That's platform dependent. Different OS'es use different #defines. If you're lucky, Boost has a portable wrapper hidden away somewhere. But otherwise, you'll just have to check for the platform-specific ones. Which platform are you running on by the way?
    • veefu
      veefu about 15 years
      Edited the question... code targets windows, solaris, and linux primarily, with parts also running on AIX and HP-UX.
    • mmmmmmmm
      mmmmmmmm about 15 years
      Just an idea: #if sizeof(int) == 64
    • veefu
      veefu about 15 years
      @rstevens: I think comments in one of the answers below says that the #if and sizeof(int) are executed at different times. When preprocessor does its job, the sizeof operator hasn't been executed.
    • Michael Burr
      Michael Burr about 15 years
    • Cory Klein
      Cory Klein over 10 years
    • phuclv
      phuclv over 8 years
      possible duplicate of Determining 32 vs 64 bit in C++
  • visual_learner
    visual_learner about 15 years
    Agreed. Tested on GCC 4.0.1 on OS X Leopard.
  • JaredPar
    JaredPar about 15 years
    Will ia64 be true for a normal intel64 bit compile? Or is there a amd64 or the like?
  • visual_learner
    visual_learner about 15 years
    I have no experience with 64-bit architectures (or with programming on non-Intel architectures), but according to the predefs page, there is an amd64 for 64-bit AMD. ia64 appears to be x86-specific.
  • veefu
    veefu about 15 years
    i386 would only work when compiling for intel cpu, correct? On solaris we compile for sparc-s2.
  • visual_learner
    visual_learner about 15 years
    @veefu - Yes, SPARC chips will have a different macro. Most likely, you can use sparc or something similar. There are about three similar but different macros for each platform that you can use, especially for GCC. Check the predefs page.
  • Jens Luedicke
    Jens Luedicke about 15 years
    This would include both 32 bit and 64 bit code in the same executable/library. I dont like this approach, because it depends on a pointer being 4 or whatever bytes long. A bad practice.
  • veefu
    veefu about 15 years
    Ok, sounds like this, combined with some gcc investigation per Chris' comments may do the trick. +1 both of you.
  • veefu
    veefu about 15 years
    The trouble with that is even though the system being used for compilation is 64-bit, it may be compiling a 32-bit executable. You are right, though, that this information must be exposed somehow in the makefile. The compiler must be told whether 32 or 64 is targetted. Should be able to adapt that.
  • veefu
    veefu about 15 years
    That's almost it. We don't have a large number of files open, but the server handles a large number of connections from clients. Socket handles and file descriptors seem to come from the same place. When we have a lot of connections, 'fopen' fails because the system-level call returns and fd > 255.
  • Nathaniel Sharp
    Nathaniel Sharp about 15 years
    If you build for only a 32 bit platform the compiler would only instantiate the code for the 32 bit platform. The whole point about the dependency if a pointer is 4 or 8 bytes is to distinguish a 32bit from a 64 bit platform
  • veefu
    veefu about 15 years
    Yes, that's almost exactly what I've implemented. wrapped calls to 'socket' and 'accept' with code that calls 'fcntl' to duplicate the handle when < 255, close the original, and use the higher one. This works well, but must be isolated to the platform its needed. Hence question about #ifdef.
  • Michael Burr
    Michael Burr about 15 years
    ia64 will not be defined for x86, x64, or amd64 builds - the ia64 is a completely different CPU architecture that has no relationship to x86 (except that Intel was involved in its development).
  • Nathaniel Sharp
    Nathaniel Sharp about 15 years
    Actually the reason I picked the size of the pointer is that it is more reliable than the size of the int itself.
  • Max Lybbert
    Max Lybbert about 15 years
    Thinking it over I think I would go with sizeof(void*).
  • Max Lybbert
    Max Lybbert about 15 years
    I just mean I agree that using pointers (1) communicates what you're looking for better, and (2) is guaranteed to work even on a platform that understands "natural size" differently than I do ( unix.org/version2/whatsnew/lp64_wp.html ).
  • Bastien Léonard
    Bastien Léonard almost 13 years
    @Max Lybbert: I know I'm late here, but I just got an upvote on this thread so there are still people reading this. This a non sequitur. On x86-64, int is still 32 bits, and it makes perfects sense if you know how the instruction set works. I also downvoted this answer because, 1) it doesn't work, 2) strictly speaking, it's not guaranteed that pointers are 32 bits wide on what we call “32 bits platforms”.
  • Max Lybbert
    Max Lybbert almost 13 years
    I knew that I had a few comments on Stack Overflow that I've since learned were inaccurate. Thank you for finding this one. I've deleted it.
  • Sam Watkins
    Sam Watkins about 11 years
    This is the way to do it. #if and such are an abomination anyhow. Any decent compiler will evaluate this at compile time and remove the dead code, so it won't hurt performance.
  • András Aszódi
    András Aszódi over 5 years
    If you use C++11 then you can check the value of the macro SIZE_MAX which is the maximal value that a std::size_t type variable can hold. It is 0xFFFFFFFF on a 32-bit platform, and 0xFFFFFFFFFFFFFFFF on a 64-bit platform. The macro is provided in the header <cstdint>.