    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Debugging with the Macro Processor</title>
        <link>https://members.accu.org/index.php/articles/1670</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + CVu Journal Vol 1, #3 - Feb 1988</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c227/">013</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-227/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+227/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Debugging with the Macro Processor</h1>
<p><strong>Author:</strong>&nbsp;Martin Moene</p>
<p>
<strong>Date:</strong> 28 June 2010 08:46:00 +01:00 or Mon, 28 June 2010 08:46:00 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<p>The C macro processor is the first pass of the compiler that converts <tt>#define</tt> symbols into the data in their definitions. An example of this is:</p>

<p><pre class="programlisting">
#define TRUE 1
#define FALSE 0

main() {
if(TRUE)
   printf(&quot;TRUE&quot;);
else
if(FALSE)
   printf(&quot;FALSE&quot;);
}
</pre></p>

<p>This code is just a bit of nonsense to show how the macro processor works. Here is how it would look after the macro expansion pass of the C compiler:</p>

<p><pre class="programlisting">
main()
{
   if(1)
      printf(&quot;TRUE&quot;);
   else
   if(0)
      printf(&quot;FALSE&quot;);
}
</pre></p>

<p>Notice that <tt>TRUE</tt> has been replaced by <tt>1</tt> and <tt>FALSE</tt> has been replaced by <tt>0</tt> (a zero value is 'false' to C). The action of this program is to print the word TRUE. Notice that the strings &quot;TRUE&quot; and &quot;FALSE&quot; have been preserved. Macro processing is not just a textual substitution such as would be done with an editor.</p>

<p>An important feature of the macro processor is the ability to test the value of a defined sybmol and alter how code is compiled accordingly. The most common use of this is to selectively include extra code for debugging purposes.</p>

<p><pre class="programlisting">
#define DEBUG
.......
#ifdef DEBUG
   printf(&quot;some debugging message....&quot;);
#endif
</pre></p>

<p>If you wish to remove the debugging printf from the program then the only thing that needs to be removed is the &quot;<tt>#define DEBUG</tt>&quot; as if the symbol &quot;<tt>DEBUG</tt>&quot; is not defined the first pass of the compiler will omit everything between an <tt>#ifdef DEBUG</tt> and its matching <tt>endif</tt>. For only one message this is little different from the work involved in placing a comment arount the printf statement to get the same result but if the program has many debugging messages instead of one then it is much quicker to control them with the macro processor.</p>

<p>With some compilers it is possible to supply definitions to the macro processor on the command line so the <tt>#define DEBUG</tt> need not be present in the file itself.</p>

<p>Unlike comments <tt>ifdef</tt>/<tt>endif</tt> pairs can be nested, each <tt>endif</tt> will match the most recent <tt>ifdef</tt>. If there are many <tt>ifdef</tt>/<tt>endif</tt> pairs in the code it is a good idea to 'tag' each <tt>endif</tt> with the <tt>ifdef</tt> it belongs to to save confusion - like this:</p>

<p><pre class="programlisting">
#ifdef DEBUG
   printf(&quot;some debugging message....&quot;);
#endif /* DEBUG */
</pre></p>

<p>The comments around the second <tt>DEBUG</tt> may not be need for all compilers but</p>

<p>Microsoft C for one complains about extra characters after an endif directive. As comments are the first things to be stripped out by the macro processor a comment can be put anywhere without changing the sense of anything.</p>

<p>What I have just presented above is the 'traditional' way to include debugging code. If more use is made of macro processor features debugging can be made easier and neater.</p>

<p>The most powerful feature of the macro processor is that macros are allowed to have paramerets. The best way to explain this is with an example:</p>

<p><pre class="programlisting">
#define MAC(A, B, C) (A = B * C)</p>

main()
{
   int v1, v2, v3;
   v2 = v3 = 10;
   MAC(v1, v2, v3);
}
</pre></p>

<p>will exand to:</p>

<p><pre class="programlisting">
main()
{
   int v1, v2, v3;
   v2 = v3 = 10;
   v1 = v2 * v3;
}
</pre></p>

<p>Although the use of macros with parameters looks like function calls the effect is to 'expand' into the code of the macro definition. The <tt>MAC</tt> macro above simply wouldn't work as a function. If <tt>v1</tt> was a parameter it could not be assigned the value of <tt>v2 * v3</tt>.</p>

<p>The last tool we need to be aware of before building our debug tools is the 'special' macro names. There are two symbols that the macro processor defines for itself but are accesable inside other macro definitions. The macro <tt>__LINE__</tt> (note the double underscores on each side of the definition) is the current line number that the macro processor has got to in the source file and <tt>__FILE__</tt> is a string containing the name of the current file being processed. These are two things that are very useful to know in a debug message!</p>

<p>Here then is the first of my debug macros:</p>

<p><pre class="programlisting">
#ifdef DEBUG 
   #define DEBUG0(S) {printf(&quot;%s(%d) %s&quot;, __FILE__, __LINE__, S);}
#else
   #define DEBUG0(S)
#endif
</pre></p>

<p>Note that if <tt>DEBUG</tt> is not defined the <tt>DEBUG0()</tt> macro has no body. This means that any <tt>DEBUG0</tt> in the code will dissappear if <tt>DEBUG</tt> is not defined. Instead of having to brace the <tt>printf</tt> with <tt>#ifdef DEBUG</tt>/<tt>#endif</tt> in the code every time it is used the <tt>DEBUG0</tt> can be used directly in place of the <tt>printf</tt>.</p>

<p>Here we come across a difference between macros and functions that requires some thought. The <tt>printf</tt> function can take a variable number of arguments but the above macro can only take one argument so it is only any good for printing constant strings. The only way around this is to have a range of <tt>DEBUG</tt> macros that accept different numbers of arguments. Here is one that will accept a printf format string and two variable items to print:</p>

<p><pre class="programlisting">
DEBUG3(S, X, Y) {printf(&quot;%s(%d) &quot;,__FILE__, __LINE__); \ 
   printf(S, X, Y); }
</pre></p>

<p>A good convention is to end the name of the macro with the number of argumets it expects.</p>

<p>Another common way of debugging is to put an if statement around the printf so that the message is only printed if a condition is true. This can also be catered for neatly as a simple macro - just a variant of the <tt>DEBUG</tt> macro set discussed above. Here is a the <tt>DEBUG3</tt> macro with an added <tt>if</tt> part:</p>

<p><pre class="programlisting">
IFDEBUG3(C, S, X, Y) if(C){printf(&quot;%s(%d) &quot;,__FILE__, __LINE__); \
   printf(S, X, Y); }
</pre></p>

<p>The message is only printed if condition <tt>C</tt> is true. <tt>C</tt> can be anything that would be legal in an if statement.</p>

<p><pre class="programlisting">
IFDEBUUG3(x &gt; 10 &amp;&amp; y &gt; 20, &quot;x is %d and y is %d\n&quot;, x, y);
</pre></p>

<p>Sensible use of macros can do much to make C programming easier to do and C programs easier to read. If debugs only take one line instead of 3 or more then they detract much less from the readability of the underlying program.</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
