1 | <html> |
---|
2 | <head> |
---|
3 | <title>problems.html</title> |
---|
4 | <link rel="stylesheet" type="text/css" href="../styles.css"> |
---|
5 | </head> |
---|
6 | <body> |
---|
7 | <h4>Known Problems of the C/C++ Preprocessor</h4> |
---|
8 | <div> |
---|
9 | Preprocessor metaprogramming is subject to heated discussions. |
---|
10 | Part of this is caused by bad experiences with dangerous techniques, |
---|
11 | such as defining inline functions using macros. |
---|
12 | As a rule of thumb, if you can find a clean and manageable way to do something |
---|
13 | without the preprocessor, then you should do it that way. |
---|
14 | </div> |
---|
15 | <div> |
---|
16 | Let's survey some of the widely known problems of the preprocessor in a problem/solution format. |
---|
17 | </div> |
---|
18 | <h4>Problem #1</h4> |
---|
19 | <div> |
---|
20 | The preprocessor does not respect scope, therefore macros can accidentally and sometimes silently replace code. |
---|
21 | </div> |
---|
22 | <div> |
---|
23 | <b>Solution A</b> |
---|
24 | <div> |
---|
25 | Use all caps identifiers for macros and only macros. |
---|
26 | This practically eliminates the possibility that a macro might replace other kinds of code accidentally. |
---|
27 | </div> |
---|
28 | </div> |
---|
29 | <div> |
---|
30 | <b>Solution B</b> |
---|
31 | <div> |
---|
32 | Use the local macro idiom: |
---|
33 | </div> |
---|
34 | <div class="code"><pre> |
---|
35 | #define MACRO ... |
---|
36 | // use MACRO |
---|
37 | #undef MACRO |
---|
38 | </pre></div> |
---|
39 | <div> |
---|
40 | This makes sure that a macro cannot accidentally replace code outside of the scope of the local macro. |
---|
41 | </div> |
---|
42 | <div> |
---|
43 | A problem with this solution is that the #undef cannot be automated and may be forgotten. |
---|
44 | Experienced programmers generally write the #undef either immediately before (in time) |
---|
45 | or immediately after writing the macro definition. |
---|
46 | </div> |
---|
47 | </div> |
---|
48 | <div> |
---|
49 | <b>Solution C</b> |
---|
50 | <div> |
---|
51 | Use the unique macro prefix idiom. |
---|
52 | </div> |
---|
53 | <div class="code"><pre> |
---|
54 | #define UMP_MACRO |
---|
55 | // use UMP_MACRO |
---|
56 | </pre></div> |
---|
57 | <div> |
---|
58 | This makes accidental substitution and collisions highly unlikely. |
---|
59 | Problems with this solution include: |
---|
60 | </div> |
---|
61 | <ul> |
---|
62 | <li>There can still be naming collisions inside a large project.</li> |
---|
63 | <li>Macros still pollute the global namespace.</li> |
---|
64 | </ul> |
---|
65 | <i>By combining all solutions, whenever possible, the scope problem can be largely avoided.</i> |
---|
66 | </div> |
---|
67 | <h4>Problem #2</h4> |
---|
68 | <div> |
---|
69 | Preprocessor code is difficult to read. |
---|
70 | It requires an understanding of the basic process of how the preprocessor recursively expands macros, |
---|
71 | finding macro definitions, and mentally substituting the parameters of the macro. |
---|
72 | </div> |
---|
73 | <div> |
---|
74 | <b>Solution</b> |
---|
75 | <div> |
---|
76 | Any kind of programming requires a basic understanding of how the code is executed. |
---|
77 | Any parameterization technique, including simple functions and templates requires finding |
---|
78 | the definition and mentally substituting parameters. |
---|
79 | </div> |
---|
80 | <div> |
---|
81 | However, it is good to know a few techniques: |
---|
82 | </div> |
---|
83 | <ul> |
---|
84 | <li>By using as many local macros as reasonable, the bulk of the searching process can be eliminated.</li> |
---|
85 | <li>Code browsers and text search tools make it easier to find the definitions.</li> |
---|
86 | <li>The compiler can be used for generating the preprocessed source code in order to look for bugs.</li> |
---|
87 | <li> |
---|
88 | Before turning something into a preprocessor metaprogram, first implement a small scale version |
---|
89 | of it without the preprocessor. |
---|
90 | The work bottom-up, replacing hand-written constructs by using the preprocessor. |
---|
91 | This way you can test the code incrementally. |
---|
92 | Experienced programmers often skip many stages, but if something proves too complex to write |
---|
93 | directly, it is always possible to fall back to incremental methods. |
---|
94 | </li> |
---|
95 | <li> |
---|
96 | If you insert a special symbol into the preprocessor code in places where there should be a line break, |
---|
97 | you can make code readable after preprocessing simply by using a search and replace tool. |
---|
98 | </li> |
---|
99 | </ul> |
---|
100 | <i>An especially important thing to remember is to limit the use of the preprocessor to |
---|
101 | structured, well-understood, and safe methods. |
---|
102 | Structure helps to understand complex systems <a href="../bibliography.html#mcconnell">[McConnell]</a>.</i> |
---|
103 | </div> |
---|
104 | <h4>Problem #3</h4> |
---|
105 | <div> |
---|
106 | "I'd like to see Cpp abolished." - <i>Bjarne Stroustrup</i> in <a href="../bibliography.html#stroustrup">[Stroustrup]</a>. |
---|
107 | </div> |
---|
108 | <div> |
---|
109 | <b>Solution</b> |
---|
110 | <div> |
---|
111 | The C/C++ preprocessor will be here for a long time. |
---|
112 | </div> |
---|
113 | <i>In practice, preprocessor metaprogramming is far simpler and more portable than template metaprogramming <a href="../bibliography.html#czarnecki">[Czarnecki]</a>.</i> |
---|
114 | </div> |
---|
115 | <hr size="1"> |
---|
116 | <div style="margin-left: 0px;"> |
---|
117 | <i>© Copyright <a href="http://www.housemarque.com" target="_top">Housemarque Oy</a> 2002</i> |
---|
118 | </div> |
---|
119 | <div style="margin-left: 0px;"> |
---|
120 | Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. |
---|
121 | This document is provided "as is" without express or implied warranty and with no claim as to its suitability for any purpose. |
---|
122 | </div> |
---|
123 | <hr size="1"> |
---|
124 | <div style="margin-left: 0px;"> |
---|
125 | <i>© Copyright <a href="http://www.housemarque.com" target="_top">Housemarque Oy</a> 2002</i> |
---|
126 | </br><i>© Copyright Paul Mensonides 2002</i> |
---|
127 | </div> |
---|
128 | <div style="margin-left: 0px;"> |
---|
129 | <p><small>Distributed under the Boost Software License, Version 1.0. (See |
---|
130 | accompanying file <a href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or |
---|
131 | copy at <a href= |
---|
132 | "http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p> |
---|
133 | </div> |
---|
134 | </body> |
---|
135 | </html> |
---|