7

I need to set #ifdef - checks for conditional compile. I want to automate the process but cannot specify the target OS/machine. Is there some way that the pre-compiler can resolve whether it it is running on 32-bit or 64-bit?

(Explanation) I need to define a type that is 64 bits in size. On 64bit OS it is a long, on most others it is a long long.

I found this answer - is this the correct way to go?

[edit] a handy reference for compiler macros

Community
  • 1
  • 1
slashmais
  • 7,069
  • 9
  • 54
  • 80
  • 3
    What exactly is your definition of a 64-bit system? (This is a serious question) – NPE Jul 15 '11 at 11:06
  • Why does it matter to your program? – lhf Jul 15 '11 at 11:06
  • 4
    So do you want the code to compile the code as 32-bit if the compiler is running on a 32-bit machine or 64-bit if the compiler is running on a 64-bit machine? I don't quite understand your question. Also I find it rather difficult to believe that you cannot specify the target OS/machine, especially if you're the one compiling the source. – In silico Jul 15 '11 at 11:08
  • There is no standard define for the 'bitness' of the target system in the pre-compiler. You either have to pass your own, or rely on those defined by the compiler itself. E.g. _WIN64 – Christopher Jul 15 '11 at 11:14

8 Answers8

10

The only compile check you can do reliably would be sizeof(void*) == 8, true for x64 and false for x86. This is a constexpr and you can pass it to templates but you can forget using ifdef with it. There is no platform-independent way to know the address size of the target architecture (at pre-process time), you will need to ask your IDE for one. The Standard doesn't even have the concept of the address size.

Puppy
  • 144,682
  • 38
  • 256
  • 465
4

No there is no standard language support for macro to determine if the machine is a 64-bit or 32-bit at preprocessor stage.

iammilind
  • 68,093
  • 33
  • 169
  • 336
4

In response to your edit, there is a "macro-less for you" way to get a type that is 64 bits.

if you need a type that can hold 64 bits, then #include <cstdint> and use either int64_t or uint64_t. You can also use the Standard Integer Types provided by Boost.

Another option is to use long long. It's technically not part of the C++ standard (it will be in C++0x) but is supported on just about every compiler.

In silico
  • 51,091
  • 10
  • 150
  • 143
2

Boost has absorbed the old Predef project. You'll want the architecture macros, more specifically BOOST_ARCH_X86_32/BOOST_ARCH_X86_64, assuming you only care about x86.

If you need a wider detection (e.g. ARM64), either add the relevant macro's to your check, or check what you actually want to check, e.g.

sizeof(void*) == 8
rubenvb
  • 74,642
  • 33
  • 187
  • 332
  • This is the problem with link-only answers: the link is dead, and I have no idea how to solve my problem using this "answer". – Violet Giraffe Mar 31 '19 at 15:55
2

I would look at source code for a cross-platform library. It is a quite large part. Every pair of OS and compiler has own set of definitions. Few libraries You may look at:
http://www.libsdl.org/ \include\SDL_config*.h (few files)
http://qt.nokia.com/ \src\corelib\global\qglobal.h

Michas
  • 8,534
  • 6
  • 38
  • 62
1

Well, the answer is clearly going to be OS-specific, so you need to narrow down your requirements.

For example, on Unix uname -a typically gives enough info to distinguish a 32-bit build of the OS from a 64-bit build.

The command can be invoked by your pre-compiler. Depending on its output, compiler flags can be set appropriately.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
0

I would be tempted to hoist the detection out of the code and put that into the Makefile. Then, you can leverage system tools to detect and set the appropriate macro upon which you are switching in your code.

In your Makefile ...

<do stuff to detect and set SUPPORT_XX_BIT to the appropriate value>
gcc myFile.c -D$(SUPPORT_XX_BIT) -o myFile

In your code ...

#if defined(SUPPORT_32_BIT)
...
#elif defined(SUPPORT_64_BIT)
...
#else
    #error "Select either 32 or 64 bit option\n"
#endif
Sparky
  • 13,505
  • 4
  • 26
  • 27
-2

Probably the easiest way might be comparing the size of int and long long. You cannot do it in the pre-processor though but you can use it in static_assert.

Edit: WoW all the negative votes. I made my point a bit more clear. Also it appears I should have mentioned 'long long' rather than 'long' because of the way MSVC works.

AlefSin
  • 1,086
  • 9
  • 20