mirror of
https://github.com/boostorg/preprocessor.git
synced 2025-07-04 00:06:32 +02:00
114 lines
4.7 KiB
HTML
114 lines
4.7 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||
<HTML><HEAD><TITLE>Boost PREPROCESSOR library</TITLE>
|
||
<BODY bgcolor="#ffffff">
|
||
<a href="index.htm"><IMG height=86
|
||
alt="c++boost.gif (8819 bytes)"
|
||
src="../../../c++boost.gif"
|
||
width=277 align=center></a>
|
||
<hr>
|
||
|
||
<h1>Boost PREPROCESSOR library: Widely known problems with the C preprocessor</h1>
|
||
|
||
<p>
|
||
|
||
Preprocessor metaprogramming is subject to heated discussions. Part of this is caused by
|
||
bad experiences with dangerous techniques, such as defining inline functions using macros. As a rule
|
||
of thumb, if you can find a clean and
|
||
manageable way to do something without using the preprocessor, then
|
||
you should do it that way.</p>
|
||
|
||
<p>Let's survey some of the widely known problems with the preprocessor in a problem/solution
|
||
format.</p>
|
||
<HR>
|
||
|
||
<p><B>PROBLEM:</B> Preprocessor does not
|
||
respect scope, therefore macros can accidentally and sometimes silently replace
|
||
code.</p>
|
||
|
||
<p><B>SOLUTION A:</B> Use all caps identifiers
|
||
for macros and only macros. This practically eliminates the possibility that a
|
||
macro might replace other kind of code accidentally.</p>
|
||
|
||
<p><B>SOLUTION B:</B> Use the Local Macro
|
||
idiom:</p>
|
||
|
||
<blockquote><pre>#define MACRO ...
|
||
// Use MACRO
|
||
#undef MACRO
|
||
</pre></blockquote>
|
||
|
||
<p>This makes sure that a macro can not accidentally
|
||
replace code outside of the scope of the local macro.</p>
|
||
<P>A problem with this solution is that the #undef can not be automated and may be
|
||
forgotten. Experienced programmers generally write the #undef either immediately
|
||
before (in time) or immediately after writing the macro definition.</P>
|
||
<P><B>SOLUTION C:</B> Use the Unique Macro Prefix idiom:</P>
|
||
|
||
<blockquote><pre>#define UMP_MACRO
|
||
// Use UMP_MACRO
|
||
</pre></blockquote>
|
||
|
||
|
||
<P>This makes accidental substitution and collisions highly
|
||
unlikely. Problems with this solution:</P>
|
||
<UL>
|
||
<LI>
|
||
There can still be naming collisions inside a large project.
|
||
<LI>
|
||
Macros still pollute the global namespace. </LI></UL>
|
||
<P><EM><B>By combining all solutions, whenever
|
||
possible, the scope problem can be largely avoided.</B></EM></P>
|
||
<HR>
|
||
|
||
<P><B>PROBLEM:</B> Preprocessor code is difficult to read.
|
||
It requires understanding the basic process of how
|
||
the preprocessor recursively expands macros, finding the macro definition and mentally
|
||
substituting the parameters of the macro. </P>
|
||
<P><B>SOLUTION:</B> Any kind of programming requires basic understanding
|
||
of how the code is executed. Any parameterization technique, including simple
|
||
functions and templates requires finding the definition and mentally substituting
|
||
parameters. </P>
|
||
<P>However, it is good to know a few techniques:</P>
|
||
<UL>
|
||
<LI>
|
||
By using as many Local Macros as reasonable, the bulk of the searching
|
||
process can be eliminated.
|
||
<LI>
|
||
Code browsers and text search tools make it easier to find the
|
||
definitions.
|
||
<LI>
|
||
The compiler can be used for generating the preprocessed source code in
|
||
order to look for bugs.
|
||
<LI>
|
||
Before turning something into a preprocessor metaprogram, first
|
||
implement a small scale version of it without preprocessor. Then work
|
||
bottom->up replacing hand written constructs by using preprocessor. This
|
||
way you can test the code incrementally. Experienced programmers often skip
|
||
many stages, but if something proves too complex to write directly, it is
|
||
always possible to fall back to incremental methods.
|
||
<LI>
|
||
If you insert a special symbol into the preprocessor code in places where
|
||
there should be a line break, you can make code readable after preprocessing
|
||
simply by using a search and replace tool. </LI></UL>
|
||
<P><B><EM> An especially important thing to remember is to limit the use of preprocessor
|
||
to the structured, well understood and safe methods. Structure helps to understand
|
||
complex systems <A href="references.htm#[4]">[4]</A>.</EM></B></P>
|
||
<HR>
|
||
|
||
<P><B>PROBLEM:</B> "I'd
|
||
like to see Cpp abolished." - Bjarne Stroustrup in <A href="references.htm#[1]">[1]</A></P>
|
||
<P><B>SOLUTION:</B> The C preprocessor will be here for a
|
||
long time.</P>
|
||
<P><EM><B>In practice, preprocessor metaprogramming is far simpler and more portable
|
||
than template metaprogramming <A href="references.htm#[2]">[2]</A>.</B></EM></P>
|
||
<hr>
|
||
<P><EFBFBD> Copyright Housemarque Oy 2001</P>
|
||
<p>Permission to copy, use, modify, sell and distribute this document is granted
|
||
provided this copyright notice appears in all copies. This document is provided
|
||
"as is" without express or implied warranty, and with no claim as to its suitability
|
||
for any purpose. </p>
|
||
<p>Updated: <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan --><!--webbot bot="Timestamp" endspan i-checksum="15246" --></p>
|
||
<p></p>
|
||
|
||
</BODY></HTML>
|