C preprocessor: Difference between revisions

Jump to navigation Jump to search
Unstubbed predefined tokens and added some information.
[unchecked revision][unchecked revision]
(Some more work. Everything beyond the stub template hasn't been overworked yet.)
(Unstubbed predefined tokens and added some information.)
Line 1:
The C preprocessor is the first step in the process of translating C/C++ source code into a binary. (preprocessingGenerally, ->the process walked through is preprocessing, compiling ->and finally linking). In trivial environments, the preprocessor is used only for '''#include'''ing header files, and providing "header guards" to avoid multiple inclusions. However, the preprocessor can do much more, and can be very useful - not only for C/C++ sources, but for your Assembly sources as well. Use it with care, since it can also obfuscate your source code and introduce bugs that may be very difficult to debug.
== C preprocessor ==
 
The C preprocessor is the first step in the process of translating C/C++ source code into a binary (preprocessing -> compiling -> linking). In trivial environments, the preprocessor is used only for '''#include'''ing header files, and providing "header guards" to avoid multiple inclusions.
 
But the preprocessor can do much more, and can be very useful - not only for C/C++ sources, but for your Assembler sources just as well.
 
It should be used with care and moderation though, because it can also obfuscate your source code and introduce bugs that are very difficult to debug.
 
=== General ===
 
=== General ===
The preprocessor handles ''preprocessor directives'', which are lines that begin with '' '#' ''. Really old compiler versions demanded that the '' '#' '' be placed in column 1, modern versions of C and C++ allow preprocessor directives to begin in any column, as long as the first non-whitespace character of the line is '' '#' ''.
 
Lines with preprocessor directives can be "continued" by placing a backslash ('\') as the last character of the line.
 
=== Includes ===
 
The most familiar use of the preprocessor is to include header files (containing function declarations, definition of constants etc.):
 
Line 30 ⟶ 22:
Another possible use is "templating" a piece of code that keeps recurring in more than one source file but could not be put into a seperate function. This way, you could still reduce redundancy by keeping the shared code in a single file and merely ''#include''ing it where needed. This, however, is a pretty ugly construct and should be avoided if possible.
 
=== Preprocessor Macros, pt. 1 ===
 
The preprocessor can ''define'' tokens. It is good custom to write these tokens in ALL CAPS. (See pt. 2 as for why.)
 
Line 40 ⟶ 31:
Most compilers also allow the definition of preprocessor tokens on the command line, e.g. the "-D MYTOKEN" option for [[GCC]].
 
=== Conditional Compilation ===
 
The preprocessor can ''conditionally'' select which parts of source code to compile, depending on whether a given token is defined or not (see above).
 
Line 60 ⟶ 50:
Note that such ''#if'' / ''#ifdef'' / ''#ifndef'' - ''#endif'' sections can be nested.
 
=== Header Guards ===
 
Non-trivial projects face the problem that a header file includes other header files in turn. Let's say both ''abc.h'' and ''def.h'' both include ''xyz.h''. Should you ''#include'' both ''abc.h'' and ''def.h'' in your source, you will likely end up with warnings and errors about redefinitions etc.
 
Line 77 ⟶ 66:
</source>
 
=== Preprocessor Macros, pt. 2 ===
 
Preprocessor tokens can also be assigned a ''value''.
 
Line 114 ⟶ 102:
Such code can easily be re-enabled temporarily with no more effort than replacing the "0" with a "1". Source comments as to why you disabled code this way are in order.
 
=== #undef ===
 
Using the ''#undef'' directive, a preprocessor token can be undefined. This is useful for trickier setups where you might want to redefine a token to a different value: Redefinitions generate a warning message, undefinitions of undefined tokens don't.
 
This should not be constructed as an advice to ''always'' use ''#undef'' before a ''#define''. Those warnings might actually be pointing to a real problem in your logic. Use ''#undef'' with care.
 
=== Predefined Tokens ===
The preprocessor provides thea tokenscouple ''__FILE__'',of ''__LINE__'' and ''__func__'',tokens which are automatically defined to the appropriate values - something very useful when constructing error messages or tracing messages. Note that some obsolete compilers might balk at ''__func__'' and not all tokens may be supported or implemented by all compilers.
 
The preprocessor provides the tokens ''__FILE__'', ''__LINE__'' and ''__func__'', which are automatically defined to the appropriate values - something very useful when constructing error or tracing messages. Note that some obsolete compilers might balk at ''__func__''.
 
{| {stub{wikitable}}
! Preprocessor Token
! Explanation
|-
| __FILE__ || Holds the name of the current source file being compiled (as a string).
|-
| __LINE__ || Holds the current line being compiled (as an integer).
|-
| __DATE__ || Holds the date when the compilation process began (a string with the format "Mmm dd yyyy").
|-
| __TIME__ || Same as the previous, but the time (a string with the format "hh:mm:ss").
|-
| __cplusplus || When defined, the value indicates that C++ compilation is active. When the compiler is (fully) compliant to the standards, the value should be >= 199711L.
|-
| __STDC__ || When defined, the value indicates that the compiler is (fully) compliant with the ANSI C standard.
|-
| __func__ || Holds the name of the function it is used within (as a string).
|}
 
Different compilers may define extra preprocessor tokens. Visual C++ for example may define _MSC_VER __cplusplus_cli. See the link section below for more information.
=== assert() ===
 
=== assert() ===
Assertions are used to catch situations which should never happen, even under error circumstances. If the condition given in the parantheses does not evaluate to "true", a diagnosis is printed which contains source file name, line number, and (since C99) name of the current function; the program then calls abort().
 
Line 168 ⟶ 172:
#endif
</source>
 
== Hazards of the C preprocessor ==
 
There is a number of counter-intuitive consequences of macros and macro expanding design.
[http://gcc.gnu.org/onlinedocs/cpp/Macro-Pitfalls.html#Macro-Pitfalls Macro Pitfalls]
 
== See also ==
=== Articles ===
 
* [[C]]
 
=== External Links ===
There* is[http://gcc.gnu.org/onlinedocs/cpp/Macro-Pitfalls.html#Macro-Pitfalls aMacro Pitfalls] - A number of counter-intuitive consequences of macros and macro expanding design.
 
* [http://gcc.gnu.org/onlinedocs/cpp/ The GNU C preprocessor manual:]
* [http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx VC++ preprocessor information]
 
* [http://gcc.gnu.org/onlinedocs/cpp/ Index]
 
----
 
[[Category:C]]
252

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.

Navigation menu