views:

553

answers:

4

I often see __WIN32, WIN32 or __WIN32__. I assume that this depends on the used preprocessor (either one from visual studio, or gcc etc).

Do I now have to check first for os and then for the used compiler? We are using here G++ 4.4.x, Visual Studio 2008 and Xcode (which I assume is a gcc again) and ATM we are using just __WIN32__, __APPLE__ and __LINUX__.

A: 

Don't see why you have to. You might have to remember to specify the definition manually on your compiler's commandline, but that's all. For the record, Visual Studio's definition is _WIN32 (with one underscore) rather than __WIN32. If it's not defined then it's not defined, and it won't matter.

Billy ONeal
So I could write the `#ifdef __WIN32__` only once and not `#ifdef WIN32 || __WIN32 || __WIN32__`
brubelsabs
@brubelsabs: Yes, but you'd have to remember to put in the preprocessor definition yourself on the commandline if you decided to use another compiler.
Billy ONeal
A: 

I've rebuild my answer... Damn, editing berserk :P:

You don't need to use partical one. And probably for MacOSX, Linux and other Unix-likes you don't need to use any at all.

Most popular one is (as far as Google tells the truth) is _WIN32.

You never define it "by hand" in your source code. It is defined in one of these ways:
as a commandline preprocessor/compiler flag (like g++ -D _WIN32)
or it is predefined by compiler itself (most of Windows compilers predefine _WIN32, and sometimes other like WIN32 or _WIN32_ too. -- Then you don't need to worry about defining it at all, compiler does the whole work.


And my old answer:

You don't 'have to' anything. It's just for multi-platform compatibility. Often version of code for all Unix-likes (including Linux, MacOSX, BSD, Solaris...) and other POSIX platform will be completely the same and there must be some changes for Windows. So people write their code generally for Unix-likes and put some Windows-only (eg. DirectX instructions, Windows-like file paths...) parts between #ifdef _WIN32 and #endif.

If you have some parts eg. X-Window-system only, or MacOS-only, you do similar with something like #ifdef X_WINDOW or #ifdef MACOS. Then, you need set a proper preprocessor definition while compiling (with gcc using -D flag, like eg. gcc -D _WIN32).

If you don't write any platform-dependent code, then you don't need to care for such a #ifdef, #else, #endif blocks. And most of Windows compilers/preprocessors AFAIK have predefined some symbols like _WIN32 (most popular, as far as google tells the truth), WIN32, _WIN32_, etc. So compiling it on Windows most probably you don't need to make anything else than just compiling.

silmeth
Probably my question is very unclear: I don't want to define WIN32 but to use it with `#ifdef`. And I wondered why there are so many variants and if there is one which should work with most of the compiliers.
brubelsabs
As I said, people just use what they like, there is no standard. Anyway, you can define it when compiling yourself in commandline (and also in IDE options, etc.), so using "unsupported" WIN32__ instead of "good" _WIN32 isn't a problem.And, as I said, most compilers support _WIN32 and some support many others (mingw support WIN32 _WIN32 WIN32 __WIN32 MINGW32 WINNT WINNT __WINNT).See this one: http://stackoverflow.com/questions/142508/how-do-i-check-os-with-a-preprocessor-directive
silmeth
+1  A: 

It depends what you are trying to do. You can check the compiler if your program wants to make use of some specific functions (from the gcc toolchain for example). You can check for operating system ( _WINDOWS, __unix__ ) if you want to use some OS specific functions (regardless of compiler - for example CreateProcess on Windows and fork on unix).

Macros for Visual C

Macros for gcc

You must check the documentation of each compiler in order to be able to detect the differences when compiling. I remember that the gnu toolchain(gcc) has some functions in the C library (libc) that are not on other toolchains (like Visual C for example). This way if you want to use those functions out of commodity then you must detect that you are using GCC, so the code you must use would be the following:

#ifdef __GNUC__
// do my gcc specific stuff
#else
// ... handle this for other compilers
#endif
Iulian Şerbănoiu
A: 

Sigh - don't rely on compiler anything - specify which platform you are building for in your Makefile. Simply put, anything beginning with _ is implementation dependent and not portable.

I tried your method once upon a time, on a very large project, and in between bouncing around between Sun-C++ and GCC we just decided to go with Makefile control rather than trying to deduce what the compilers were going to do.

Chris Kaminski
You can create wrappers for different behaviors and use those wrappers. This way you deal with platform/compiler differences in just a few source files, which is (in my opinion) better that dealing with makefiles for each platform.
Iulian Şerbănoiu
You have a valid point. However, I can't conceive of a situation where you're supporting multiple platforms and aren't using Makefiles of some sort (gmake/cmake/qmake) anyway. Windows library definitions to link.exe are not the same as gcc -L -l. Nor are compiler optimization settings. I'd much rather deal with my platform flags in one Makefile (or a few by inclusion) than have to remember to include platform_magic.h in every header/source file. Boost does it your way - in boost/system/config.hpp it determines what platform it's running on. We'll just have to agree to disagree. :-D
Chris Kaminski