Brian Silverman | f27e085 | 2018-08-04 23:56:45 -0700 | [diff] [blame^] | 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> |