views:

376

answers:

4

Is there a simple preprocessor macro that is defined for a 64-bit build? I thought _WIN64 might have been it, but even when I build a 32-bit target, the parts enclosed in a #ifdef _WIN64 ... #endif are compiled in, and this is causing problems. It's Friday and I can't think straight, but I'm sure I'm overlooking something very simple here. Maybe even something involving sizeof.

+2  A: 

Check your project's build properties, particularly the preprocessor section. Are you defining _WIN64 somewhere in WIN32 builds? The sizeof thing probably won't work since you cannot use in a #if test.

dirkgently
The `sizeof` thing won't work for preprocessor commands, but an `if` statement that has a compile-time constant should be optimised out (i.e. `if (sizeof(long) == 4)`. I remember seeing this in GNU's implementation of `strlen`. The code only executes once or twice, so performance is not important.
dreamlax
Sorry, I meant to say, performance in my particular case is not important.
dreamlax
+7  A: 

The Visual C++ compiler defines the following macros:

  • _M_IX86 - x86 platform
  • _M_IA64 - ia64 platform
  • _M_X64 - x64 platform
Ron Pihlgren
However, `_WIN64`/`WIN64`/`_WIN32`/`WIN32` should almost always be used instead if Windows is the target - the defines you mention should be used only if you really need to deal with processor-specific differences (which should be rare) rather than differences in the OS platform (which are more common). If `_WIN64` is being improperly set in 32-bit builds, the problem should be fixed rather than skirted around.
Michael Burr
The difference is that _WIN64, etc. macros are defined by you (or for you) in your project and the _M_X64, etc. macros are defined by the compiler.
Ron Pihlgren
Sorry, I take that back - compiler defines _WIN32 and _WIN64 as well as the processor specific ones.
Ron Pihlgren
+7  A: 

I have always used _WIN64 to check if it is a 64 bit build.

N.B. _WIN32 is also always (automatically) defined by MSVC in 64 bit builds, so check for _WIN64 before you check for _WIN32:

#if defined( _WIN64 )

// Windows 64 bit code here

#elif defined( _WIN32 )

// Windows 32 bit code here

#else

// Non-Windows code here

#endif
Bruce Ikin
+3  A: 

It sounds like your problem might be related to a header or project setting improperly defining _WIN64 - that should be left to the compiler.

There's a subtle difference between WIN64 and _WIN64 (at least for the Microsoft compilers - other conpilers should follow suit, but not all do):

  • _WIN64 is defined by the compiler when it's building a program for a Windows 64-bit platform. Note that this name is in the compiler implementor's namespace (leading underscore followed by a capital letter)
  • WIN64 is defined by the Windows Platform SDK (or whatever they're calling it this year) when targeting a 64-bit platform.

So if you're only including standard headers and don't take other measures to define it, WIN64 will not be defined.

There's a similar story for _WIN32 and WIN32 - but checking other compilers: GCC 3.4.5 does define WIN32 even if only standard headers are used. As does Digital Mars.

Microsoft's compilers and Comeau do not.

Another bit of (hopefully) well known trivia is that _WIN32 and WIN32 are set when targeting 64-bit Windows platforms. Too much stuff would have broken otherwise.

Michael Burr
See http://stackoverflow.com/questions/662084/whats-the-difference-between-the-win32-and-win32-defines-in-c/662543#662543 for other trivia on names that differ by only a leading underscore.
Michael Burr
"the Windows Platform SDK (or whatever they're calling it this year)" How I hate that constant renaming! +1
sbi