chapter_3_section_5.html   [plain text]


<html>
    <head>
        <META NAME="Generator" CONTENT="Gutenberg">
		<META NAME="GeneratorVersion" CONTENT="v103.5
">
        <META http-equiv="content-type" CONTENT="text/html;charset=iso-8859-1">
        <META NAME = "Copyright" CONTENT="Copyright 2004 Apple Computer, Inc. All Rights Reserved.">
        <META NAME="IndexTitle" CONTENT="Using the C Preprocessor">
        <TITLE>Tools: HeaderDoc User's Guide: Using the C Preprocessor</TITLE>
        <base target="content">

        <LINK REL="stylesheet" TYPE="text/css" HREF="../Resources/CSS/frameset_styles.css">
        <style type="text/css"></style>
        <script language="JavaScript" src="../Resources/JavaScript/page.js"></script>
    </head>
    
    <BODY bgcolor="#ffffff" onload="initialize_page();"><a name="//apple_ref/doc/uid/TP40001215-CH337-BABGIGFB" title="Using the C Preprocessor" turn_anchor="no"></a>
        <a name="top"></a>
        <!-- start of header -->
        <!--#include virtual="/includes/framesetheader" -->
        <!-- end of header -->
        
        <!-- start of path -->
<div class="breadcrumb"><a href="http://developer.apple.com/" target="_top">ADC Home</a> &gt; <!--a logicalPath="//apple_ref/doc/uid/TP30000943"  -->Reference Library<!--/a--> &gt; <!--a logicalPath="//apple_ref/doc/uid/TP30000440"  -->Documentation<!--/a--> &gt; <!--a logicalPath="//apple_ref/doc/uid/TP30000436"  -->Tools<!--/a--> &gt; <!--a logicalPath="//apple_ref/doc/uid/TP30000436-TP30000502"  -->Darwin<!--/a--> &gt; <a logicalPath="//apple_ref/doc/uid/TP40001215-CH345" href="../intro/chapter_1_section_1.html#//apple_ref/doc/uid/TP40001215-CH345">HeaderDoc User's Guide</a> &gt; <a logicalPath="//apple_ref/doc/uid/TP40001215-CH337" href="chapter_3_section_1.html#//apple_ref/doc/uid/TP40001215-CH337">Using HeaderDoc</a> &gt; </div><br>
<!-- end of path -->
        
        <table width="100%" cellpadding=0 cellspacing=0 border=0 class="mini_nav_text"><tr>
        <td align=left scope="row">

        <!-- insert Show/Hide frames -->
        <script type="text/javascript" language="JavaScript"><!--
  
        if (self != top) {
            // loaded in frames
            document.write('<a href="'+self.location+'" target="_top"><img src="../Resources/Images/show_toc_icon.gif" width="15" height="14" border="0" style="margin-bottom: -2px;" alt=""></a> <a href="'+self.location+'" target="_top">Hide TOC</a>');
        }
        else {
            // not loaded frames
            document.write('<a href="../index.html?'+self.location+'" target="_top"><img src="../Resources/Images/show_toc_icon.gif" width="15" height="14" border="0" style="margin-bottom: -2px;" alt=""></a> <a href="../index.html?'+self.location+'" target="_top">Show TOC</a>');
        }
        //--></script>
        <!-- end Show/Hide frames -->

        </td><td align=right>
        
        <a href="chapter_3_section_4.html" target="_self">&lt; Previous Page</a><span style="margin-left: 8px"><a href="../gatherheaderdoc/chapter_4_section_1.html" target="_self">Next Page &gt;</a></span>
        
        </td>
        </tr></table>
        
        <hr>
        
        <a name="BABGIGFB" title="Using the C Preprocessor" turn_anchor="no"></a><h2>Using the C Preprocessor</h2>
<p>Beginning in HeaderDoc 8.5, HeaderDoc contains a basic C preprocessor
implementation (enabled with the <tt>-p</tt> flag).
Because HeaderDoc does not have access to the full compile-time
environment of the headers, its behavior may differ from normal
C preprocessors in certain cases. This section describes some of
those differences.</p>



    <h4>In this section:</h4>

    
    
    
    <blockquote class="content_text">
        
            <a logicalPath="//apple_ref/doc/uid/TP40001215-CH337-CIHHAGHH" href="chapter_3_section_5.html#//apple_ref/doc/uid/TP40001215-CH337-CIHHAGHH">Parsing Rules</a>
            
        <br>

            <a logicalPath="//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_51" href="chapter_3_section_5.html#//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_51">Multiply-Defined Macros</a>
            
        <br>

            <a logicalPath="//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_52" href="chapter_3_section_5.html#//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_52">Embedded HeaderDoc Comments in a Macro</a>
            
        <br>

            <a logicalPath="//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_53" href="chapter_3_section_5.html#//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_53">Handling of #include</a>
            
        <br>

            <a logicalPath="//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_54" href="chapter_3_section_5.html#//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_54">Other Issues</a>
            
        <br>

            <a logicalPath="//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_55" href="chapter_3_section_5.html#//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_55">What if I Don&#8217;t Want to See the Macros in the Documentation?</a>
            
        <br>

    </blockquote><br>
<a name="//apple_ref/doc/uid/TP40001215-CH337-CIHHAGHH" title="Parsing Rules" turn_anchor="no"></a><a name="CIHHAGHH" title="Parsing Rules" turn_anchor="no"></a><h3>Parsing Rules</h3>
<p>Most <tt>#define</tt> macros
are not parsed by default, even if the preprocessor is enabled.
This permits you as the user to choose which macros to process.</p>
<p>Macros are processed if any of the following are true:</p>
<ul class="ul"><li class="li"><p>They are
preceded by a HeaderDoc comment block.</p></li>
<li class="li"><p>They appear between the beginning and end of a class that
is preceded by a HeaderDoc comment block.</p></li></ul>
<p>The reason for this second case is a side-effect of the way
that HeaderDoc parses classes to ensure that lines are processed
in the order in which they appear in the file (which is necessary
for a preprocessor to even be possible). For maximum control, preprocessor directives
should be at the start of the file, outside of class braces.</p>
<a name="//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_51" title="Multiply-Defined Macros" turn_anchor="no"></a><a name="DontLinkElementID_51" title="Multiply-Defined Macros" turn_anchor="no"></a><h3>Multiply-Defined Macros</h3>
<p>HeaderDoc does not attempt to handle <tt>#if</tt>, <tt>#ifdef</tt>,
or <tt>#ifndef</tt> directives.
This may, in certain circumstances, result in multiple definitions
of a <tt>#define</tt> directive
if the preprocessor is enabled. As with most preprocessors, all
such definitions are ignored except for the one that appears first
in the file.</p>
<p>This is made slightly more complicated by the parsing rules
described in <span class="content_text"><a logicalPath="//apple_ref/doc/uid/TP40001215-CH337-CIHHAGHH" href="chapter_3_section_5.html#//apple_ref/doc/uid/TP40001215-CH337-CIHHAGHH">&#8220;Parsing Rules&#8221;</a></span>.</p>
<a name="//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_52" title="Embedded HeaderDoc Comments in a Macro" turn_anchor="no"></a><a name="DontLinkElementID_52" title="Embedded HeaderDoc Comments in a Macro" turn_anchor="no"></a><h3>Embedded HeaderDoc Comments
in a Macro</h3>
<p>With most data types, HeaderDoc comments appearing inside
the data type are associated with the data type itself. This is
normally true for <tt>#define</tt> macros
as well. However, that behavior would create a problem when the
C preprocessor is enabled, as it is reasonable to allow macros to
define contents to be blown into a class, and those contents could potentially
include HeaderDoc markup.</p>
<p>For this reason, when the C preprocessor is enabled, embedded
headerdoc processing is disabled for <tt>#define</tt> macros
marked with <tt>@parseonly</tt>.
Any HeaderDoc markup within the body of such a macro will be blown
in wherever the macro is used, and will only be processed in the
resulting context.</p>
<p>While HeaderDoc does allow a macro to insert multiple declarations
and HeaderDoc comment blocks within a class, it does not allow this
outside of a class. When a macro inserts HeaderDoc comments outside
of a class scope, parsing will end at the end of the first declaration
and any other contents inserted by the macro will be skipped.</p>
<a name="//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_53" title="Handling of #include" turn_anchor="no"></a><a name="DontLinkElementID_53" title="Handling of #include" turn_anchor="no"></a><h3>Handling of #include</h3>
<p>HeaderDoc&#8217;s implementation of <tt>#include</tt> behaves
differently than you might expect. The differences include the following:</p>
<ul class="ul"><li class="li"><p>No notion
of paths.</p><p>Because the include paths are not specified as they
are with a compiler, HeaderDoc cannot reasonably determine that <code>&lt;dir1/file.h&gt;</code> and <code>&lt;dir2/file.h&gt;</code> are
distinct. For this reason, processing files with the same name in
different directories is discouraged.</p></li>
<li class="li"><p>Mandatory recursion protection.</p><p>Because HeaderDoc does
not process <tt>#if</tt>, <tt>#ifdef</tt>,
and <tt>#ifndef</tt> conditionals,
HeaderDoc enforces recursion protection by not allowing a file to
get processed twice. Once a file is processed, a precompiled copy
of its macros is stored for future use, and is automatically inserted
whenever another <tt>#include</tt> requests
it.</p><p>While most well-behaved headers will be handled
correctly, this has two potential side-effects in a few cases. They
are as follows:</p><p><ul class="nested"><li class="nested li"><p>A <tt>#include</tt> cannot
be altered in a context-dependent way&#8212;that is, if a header incudes <tt>&lt;a.h&gt;</tt> and
then <tt>&lt;b.h&gt;</tt>, the
macros defined in <tt>&lt;a.h&gt;</tt> will
not automatically affect the parse of <tt>&lt;b.h&gt;</tt>.
In the rare cases where this matters, it can be fixed by making
sure that <tt>&lt;b.h&gt;</tt> includes <tt>&lt;a.h&gt;</tt>.</p></li>
<li class="nested li"><p>The <tt>#include</tt> directive
behaves much like <tt>#import</tt>.
The result is that if <code>&lt;a.h&gt;</code> includes <code>&lt;b.h&gt;</code> which
includes <code>&lt;c.h&gt;</code> which includes <code>&lt;a.h&gt;</code>,
the definitions leading up to the reinclusion of <tt>&lt;a.h&gt;</tt> will
not affect the way <tt>&lt;a.h&gt;</tt> is
parsed. Granted, such use of macros borders on obfuscated C, but
in theory, it <i>could</i> cause unexpected behavior....</p></li></ul></p></li>
<li class="li"><p>Macro contents will be shown in the documentation output.</p><p>Rather
than try to carry around some notion of the original tokens read
from the file, HeaderDoc inserts macros into the parse tree as if
the modified version had been read from the file. This means that
it is not possible, for example, for HeaderDoc to show you the unaltered
definition of a macro that includes another macro. (The same applies
for data types, functions, and so on if they are altered by a macro,
though this is generally the expected behavior.)</p></li></ul>
<p>These differences generally do not affect headers written
in a typical fashion, but may cause problems if you are using preprocessor
directives in a nonstandard way.</p>
<a name="//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_54" title="Other Issues" turn_anchor="no"></a><a name="DontLinkElementID_54" title="Other Issues" turn_anchor="no"></a><h3>Other Issues</h3>
<p>A few common function-like preprocessor macros are predefined
within HeaderDoc itself to avoid parse problems with I/O Kit headers.
These will probably not affect you, but you should be aware of them.</p>
<p>Because HeaderDoc does not strip comments prior to processing
macros (since doing so would remove HeaderDoc markup), the preprocessor
may behave in subtly different ways. In particular, newlines are
preserved, and any closing single-line (<tt>//</tt>)
comments in macros will automatically be converted into a multi-line
(<tt>/* */</tt>) comment to avoid
causing the rest of the line to disappear when that macro actually
gets used.</p>
<p>Finally, HeaderDoc does do basic string, character, and comment
handling, even within macros. As a result, mismatched single or
double quotes within a <tt>#define</tt> macro
may cause serious problems.</p>
<a name="//apple_ref/doc/uid/TP40001215-CH337-DontLinkElementID_55" title="What if I Don&#8217;t Want to See the Macros in the Documentation?" turn_anchor="no"></a><a name="DontLinkElementID_55" title="What if I Don&#8217;t Want to See the Macros in the Documentation?" turn_anchor="no"></a><h3>What if I Don&#8217;t Want to See
the Macros in the Documentation?</h3>
<p>Most of the time, having <tt>#define</tt> macros
defined in the documentation is helpful. In some cases, though,
the macros get so big and ugly that you just want to get rid of
them. For this reason, HeaderDoc has the <tt>@parseOnly</tt> tag.</p>
<p>For example:</p>
<table><table cellpadding="8" width="100%" bgcolor="#F1F5F9" style="border: 1px solid #C9D1D7;"><tr><td scope="row"><table bgcolor="#F1F5F9" width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td><pre><code>/*! This is an ugly internal macro. @parseOnly */</code></pre></td><td><code><pre></pre></code></td></tr><tr><td scope="row"><pre><code>#define CreateStructors \</code></pre></td><td><code><pre></pre></code></td></tr><tr><td scope="row"><pre><code>    /*! Constructor */ \</code></pre></td><td><code><pre></pre></code></td></tr><tr><td scope="row"><pre><code>    blah(); \</code></pre></td><td><code><pre></pre></code></td></tr><tr><td scope="row"><pre><code>    /*! Destructor */ \</code></pre></td><td><code><pre></pre></code></td></tr><tr><td scope="row"><pre><code>    ~blah();</code></pre></td><td><code><pre></pre></code></td></tr></table></td></tr></table><br></table>
<p>By adding this tag at the end of the HeaderDoc comment block
for the macro, the macro will be parsed and used by the preprocessor,
but will not appear in the documentation.</p>

        <br><br> 
        
        <table width="100%" cellpadding=0 cellspacing=0 border=0 class="mini_nav_text"><tr>
        <td align=left scope="row">

        <!-- insert Show/Hide frames -->
        <script type="text/javascript" language="JavaScript"><!--
           
        if (self != top) {
            // loaded in frames
            document.write('<a href="'+self.location+'" target="_top"><img src="../Resources/Images/show_toc_icon.gif" width="15" height="14" border="0" style="margin-bottom: -2px;" alt=""></a> <a href="'+self.location+'" target="_top">Hide TOC</a>');
        }
        else {
            // not loaded frames
            document.write('<a href="../index.html?'+self.location+'" target="_top"><img src="../Resources/Images/show_toc_icon.gif" width="15" height="14" border="0" style="margin-bottom: -2px;" alt=""></a> <a href="../index.html?'+self.location+'" target="_top">Show TOC</a>');
        }
        //--></script>
        <!-- end Show/Hide frames -->

        </td><td align=right>
        
        <a href="chapter_3_section_4.html" target="_self">&lt; Previous Page</a><span style="margin-left: 8px"><a href="../gatherheaderdoc/chapter_4_section_1.html" target="_self">Next Page &gt;</a></span>
        
        </td>
        </tr></table>

        <br><hr><div align="center"><p class="content_text"> <!--#if expr="0=1" -->&#169; 1999, 2004 Apple Computer, Inc. All Rights Reserved. &#40;<!--#endif -->Last updated: 2004-10-27<!--#if expr="0=1" -->&#041;<!--#endif --></p></div>

        
        <!-- start of footer -->
        <!--#include virtual="/includes/framesetfooter" -->
        <!-- end of footer -->
    </BODY>
</html>