C preprocessor: Difference between revisions

[unchecked revision][unchecked revision]
Content deleted Content added
Creature (talk | contribs)
Unstubbed predefined tokens and added some information.
m Bot: Replace deprecated source tag with syntaxhighlight
 
(3 intermediate revisions by 3 users not shown)
Line 9:
The most familiar use of the preprocessor is to include header files (containing function declarations, definition of constants etc.):
 
<sourcesyntaxhighlight lang="c">
#include <stdio.h>
#include "myheader.h"
</syntaxhighlight>
</source>
 
The effect is that the contents of the given header file are pasted into the source file. The ''technical'' difference between <> and "" is that the compiler is allowed to satisfy <> includes internally, i.e. without actually accessing any on-disk files of that name. None of the prominent compilers do this, to the knowledge of the author, but it has become common practice to use <> for system headers and "" for your own header files.
Line 25:
The preprocessor can ''define'' tokens. It is good custom to write these tokens in ALL CAPS. (See pt. 2 as for why.)
 
<sourcesyntaxhighlight lang="c">
#define MYTOKEN
</syntaxhighlight>
</source>
 
Most compilers also allow the definition of preprocessor tokens on the command line, e.g. the "-D MYTOKEN" option for [[GCC]].
Line 34:
The preprocessor can ''conditionally'' select which parts of source code to compile, depending on whether a given token is defined or not (see above).
 
<sourcesyntaxhighlight lang="c">
#define MYTOKEN
 
Line 46:
/* This source will be compiled */
#endif
</syntaxhighlight>
</source>
 
Note that such ''#if'' / ''#ifdef'' / ''#ifndef'' - ''#endif'' sections can be nested.
Line 55:
The solution are ''header guards'', a combination of conditional compilation and token definition:
 
<sourcesyntaxhighlight lang="c">
/* abc.h */
 
Line 64:
 
#endif
</syntaxhighlight>
</source>
 
== Preprocessor Macros, pt. 2 ==
Line 73:
The ''#if'' statement can be used to base conditional compilation on token values. Note that the preprocessor can only work with compile-time constants. Compiler-evaluated code like `sizeof()` cannot be used in preprocessor directives. On the upside, the preprocessor can natively handle non-numerical values.
 
<sourcesyntaxhighlight lang="c">
#define MYTOKEN foo
#define OTHERTOKEN 42
Line 90:
/* Won't be compiled. */
#endif
</syntaxhighlight>
</source>
 
The ''#if'' directive also allows for a simple construct to disable a region of code without having to worry about nested ''/* ... */'' style comments:
 
<sourcesyntaxhighlight lang="c">
#if 0
/* disabled code */
#endif
</syntaxhighlight>
</source>
 
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.
Line 134:
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().
 
<sourcesyntaxhighlight lang="c">
#include <assert.h>
 
Line 140:
assert( 1 != 2 );
assert( gdt_ptr != null );
</syntaxhighlight>
</source>
 
For production code, assertions may be turned off by defining NDEBUG:
 
<sourcesyntaxhighlight lang="bash">
gcc -DNDEBUG ...
</syntaxhighlight>
</source>
 
Note that <assert.h> does not have (or need) a header guard, i.e. can be included multiple times in a source file, and that whether NDEBUG is defined or not is evaluated anew ''at every inclusion of <assert.h>''. You can thus enable / disable assertions at a very fine-grained level if necessary:
 
<sourcesyntaxhighlight lang="c">
#include <assert.h>
 
Line 171:
#include <assert.h>
#endif
</syntaxhighlight>
</source>
 
== See also ==
=== Articles ===
* [[C]]
* [[Why function implementations shouldn't be put In header files]]
 
=== External Links ===
Line 183 ⟶ 184:
 
[[Category:C]]
[[Category:Tutorials]]