This question may seem rather basic, but coming from an engineering (non computer-science) background, I was unsure about what the snippets of '#
's were in some C++ code.
A quick search led me to the concise, well-explained cplusplus tutorial page on preprocessor directives.
But why bother with the concept of preprocessor directives at all? Is it not possible to write equivalent code that can assign values to constants, define subroutines/function/macros and handle errors?
I guess I ultimately want to know when it is good practice to use such preprocessor directives, and when it is not.
You use preprocessor directives when you need to do something outside of the scope of the actual application. For instance, you'll see preprocessing done to include or not include code based on the architecture the executable is being built for. For example:
Preprocessor directives are also used to guard includes so that classes/functions etc. are not defined more than once.
Another use is for embedding versioning inside of code and libraries.
In the Makefile you have something along the lines of:
While in the code you have
It's a better-than-nothing substitute to get some reflection capabilities out of C++.
Very useful to generate variables and strings with the same names.
Preprocessing occurs before the code is compiled. It's appropriate in cases like the following
Obviously including header files you want done at compilation time not runtime. We can't do this with variables.
On the other hand. With C++ it is good practice and greatly encouraged to replace constant expressions like the following example
The reason is that you get proper typecasting and datatype handling.
Also
Is not very nice because you can write
The preprocessor would replace that with:
Which is clearly not going to give the intended result.
Instead, MAX should be a function (not a macro). If it's a function it can also provide the type in the parameter.
I have seen the preprocessor used for all sorts of interesting things. Like language keyword declaration. It can aid in readability in this case.
In short, use the preprocessor for things that must happen at compile type such as conditional includes directives. Avoid using it for constants. Avoid macros and instead use functions where possible.
Its use is very low in C++, features of the language were created to avoid problems associated with the preprocessor.
In general C++ sources, it is often seen as poor practice - particularly when there is a mean to do it using other language features. It is required for some things (i.e. platform/build dependent programs and generative programs). In short, there's usually a replacement which scales well. (such as constant define as enum, or inline templates instead of macros). If you find yourself using one and you are not sure, then just ask/search if there is a better way to declare
this_code_snippet
in C++, without the preprocessor.It is used most frequently for two things which will be harder to organize without it:
Answer 1: conditional code that has to vary depending on what sort of computer it works on.
Answer 2: enabling and disabling language extensions and compatibility features seen at compile time.
The preprocessor came from C, where there were many thing you could not express. Good C++ code finds less reasons to use it than C code did, but sadly it's not quite useless.