Preprocessor Directives

Can someone tell me where preprocessor directives such as #define are useful in pure C++ programming? I've run across a freaking immense number of preprocessor directives on something I'm working on and it's frustrating. It seems to me that anything that is #defined can be a constant instead and macros could be an inline function, template, or something. I've never found the need to use them aside from guarding a header so I have no experience with their use. For example there are a few lines that say something like

#ifdef _cplusplus or
#ifdef _WIN32

Is there a set of predefined compiler or platform specific keywords that can be used? Where does the _cplusplus come from? I read through the tutorial on but it doesn't shed any light on the subject.

Thanks.

_cplusplus is a standard macro defined by all C++ compilers (AFAIK, anyway). It's used when the code is expected to be compiled by both C and C++ compilers. For example, in headers that need the extern "C" statement, which is C++ only.
_WIN32 and all of its variations are defined by compilers that produce code for Windows. Likewise, there's a unix macro defined when the compiler produces code for some POSIX system.
There are quite a few macros like these, including compiler, compiler version, language standard version, libraries, and architectures: http://predef.sourceforge.net/index.php

Here's one of my favorite macros:
#define ABS(x) ((x)<0?-(x):(x))
It's four or five times faster than abs(), even for integers (possibly due to the implicit conversion to and from floating point).
I've also used macros when I needed to do the same thing many times, but where functions weren't quite as useful. The example in particular is "parse an element from a vector and put the result into something; if there are any errors return an error code". While that can be done with a function, this:
1
2
3
ErrorCode error=parse(vector[n],something);
if (error!=NO_ERROR)
    return error;
is not as practical as
1
2
3
4
5
6
7
#define _PARSE(src,dst) {\
ErrorCode error=parse(vector[(src)],(dst));\
if (error!=NO_ERROR)\
    return error;\
}
//...
_PARSE(n,something)
Keep in mind that the assignment and check has to be done each time an element is parsed in any function.
Here's a more literal example. Notice how _GETWCSVALUE and _GETINTVALUE are all over the place:
http://onslaught-vn.svn.sourceforge.net/viewvc/onslaught-vn/trunk/src/Processing/ScriptInterpreter_commandsAI.cpp

I don't think there are many more uses for macros other than that, forced inlined functions, and creating aliases for identifiers.
Last edited on
Those are the only three I can can think of:
1. Conditional compilation
2. simulating inline functions
3. Identifiers.

C++ is basically an Application language ? I cant think of any operating system written in C++ (name mangling alone would pretty much see to that) .
So any C OS header files are going to be crammed with #define identifiers
According to the osdev Wiki, It's perfectly possible to write a kernel in C++. Name mangling is not a problem as long as it's done consistently, so using more than one compiler is right out, obviously.
Thank you both. It makes more sense now. I most likely will not find any use for them, but I guess I'll just have to put up with them in the API I'm working with. I just find that the overuse of directives makes it very very difficult to understand what the hell is going on. There's also an overuse of typedefs which is driving me nuts. You have to be intimately familiar with the code to get anything out of it.
Topic archived. No new replies allowed.