<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Preliminary C++0x support</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link href="theme/style.css" rel="stylesheet" type="text/css">
</head>
<body>
<table width="100%" border="0" cellspacing="2" background="theme/bkd2.gif">
<tr>
<td width="21"> <h1></h1></td>
<td width="885"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">Preliminary
C++0x support</font></b></font></td>
<td width="96"><a href="http://spirit.sf.net"><img src="theme/wave.gif" width="93" height="68" align="right" border="0"></a></td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="10"></td>
<td width="30"><a href="index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_reference_inputpolicy.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
<td width="20"><a href="wave_driver.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>In order to prepare a proposal for the C++ Standards committee, which should
describe certain new and enhanced preprocessor features, the Wave preprocessor
library has implemented experimental support for the following features:</p>
<p><a href="preliminary_cpp0x_support.html#variadic_macros">Variadic macros</a><br>
<a href="preliminary_cpp0x_support.html#placemarker_tokens">Placemarker tokens</a><br>
<a href="preliminary_cpp0x_support.html#token_pasting">Well defined token-pasting</a><br>
<a href="preliminary_cpp0x_support.html#macro_scoping">Macro scoping mechanism</a><br>
<a href="preliminary_cpp0x_support.html#new_alternative_tokens">New alternative tokens</a></p>
<p>The described features are enabled by the <tt>--c++0x</tt> command line option
of the <tt>Wave</tt> driver. Alternatively you can enable these features by
calling the <tt>wave::context<>::set_language()</tt> function with the
<tt>wave::support_cpp0x</tt> value. </p>
<h2><a name="variadic_macros"></a>Variadic macros</h2>
<p>Both variadic macros and placemarker tokens have already been added to C99
<a href="references.html#iso_c">[2]</a>. This represents an unnecessary incompatibility
between C and C++. Adding these facilities to the C++ preprocessor would cause
no code to break that is currently well-defined and would closing the gap between
C and C++ in this field.</p>
<p>Variadic macros were added to the C preprocessor as of C99 <a href="references.html#iso_c">[2]</a>.
They are, effectively, a way to pass a variable number of arguments to a macro.
The specific syntax is as follows:</p>
<pre> <span class="preprocessor">#define</span> A(...) <span class="preprocessor">__VA_ARGS__</span>
<span class="preprocessor">#define</span> B(a, ...) <span class="preprocessor">__VA_ARGS__</span>
A(1, 2, 3) <span class="comment">// expands to: 1, 2, 3</span>
B(1, 2, 3) <span class="comment">// expands to: 2, 3</span>
</pre>
<p>The ellipsis is used to denote that the macro can accept any number of trailing
arguments. It must always occur as the last formal parameter of the macro. The
variadic arguments passed to the macro are identified by the special symbol
<tt>__VA_ARGS__</tt> in the replacement list of a variadic macro. The use of
this symbol is prohibited in any other context.</p>
<h2><a name="placemarker_tokens"></a>Placemarker tokens</h2>
<p>Placemarker tokens (technically, preprocessing tokens) are simply a well-defined
way of passing "nothing" as a macro argument. This facility was also
added to the C preprocessor as of C99 <a href="references.html#iso_c">[2]</a>.</p>
<pre> <span class="preprocessor">#define</span> X(p) f(p)
X("abc") <span class="comment">// expands to: f("abc")</span>
X() <span class="comment">// expands to: f()</span>
<span class="preprocessor">#define</span> Y(a, b) <span class="keyword">int</span>[a][b]
Y(2, 2) <span class="comment">// expands to: int[2][2]</span>
Y(, 2) <span class="comment">// expands to: int[][2]</span>
</pre>
<p>Placemarker tokens are a natural counterpart to variadic macros. They formalize the optional nature of a variadic argument (or arguments) so that variadic macros appear similar to the variadic functions, but have been generalized to include named parameters as well.
</p>
<h2><a name="token_pasting"></a>Well defined token-pasting</h2>
<p>Currently, as of both C++98 and C99, if token-pasting results in multiple preprocessing
tokens, the behavior is undefined. For example,</p>
<pre> <span class="preprocessor">#define</span> PASTE(a, b) a <span class="preprocessor">##</span> b
PASTE(1, 2) <span class="comment">// okay</span>
PASTE(+, -) <span class="comment">// undefined behavior</span></pre>
<p>Token-pasting of unrelated tokens (i.e. token-pasting resulting in multiple
preprocessing tokens) is currently undefined for no substantial reason. It is
not dependent on architecture nor is it difficult for an implementation to diagnose.
Furthermore, retokenization is what most, if not all, preprocessors already
do and what most programmers already expect the preprocessor to do. Well-defined
behavior is simply standardizing existing practice and removing an arbitrary
and unnecessary undefined behavior from the standard.</p>
<p>To achieve well-defined behavior in this context <tt>Wave</tt> retokenizes
the result of the token-pasting and inserts the newly created token sequence
as the macro replacement text.</p>
<pre> PASTE(+, ==) <span class="comment">// expands to: += =</span></pre>
<h2><a name="macro_scoping"></a>Macro scoping mechanism</h2>
<p>One of the major problems of the preprocessor is that macro definitions do
not respect any of the scoping mechanisms of the core language. As history has
shown, this is a major inconvenience and drastically increases the likelihood
of name clashes within a translation unit. The solution is to add both a named
and unnamed scoping mechanism to the C++ preprocessor. This limits the scope
of macro definitions without limiting its accessibility. Here are the details.
</p>
<p>The scoping mechanism is implemented with the help of three new preprocessor
directives: <span class="preprocessor">#region</span>, <span class="preprocessor">#endregion</span>
and <span class="preprocessor">#import</span>. Additionally it changes minor
details of some of the existing preprocessor directives: <span class="preprocessor">#ifdef</span>,
<span class="preprocessor">#ifndef</span> and the <span class="preprocessor">operator
defined()</span>.</p>
<h3>The #region directive</h3>
<h4>Syntax</h4>
<blockquote>
<p><tt>#region <qualified-identifier></tt></p>
<p> Where <tt><qualified-identifier></tt> is an optionally qualified name
defining the name of the region to open.<br>
This name is optional. If the name is omitted a nameless region is opened.
</p>
</blockquote>
<p>If the qualified identifier starts with an <tt>'::'</tt> the name is looked
up relative to the global scope (the <tt><qualified-identifier></tt> is
called <em>absolute</em>), if it starts with an identifier, the region is looked
up relative to the current open region (the <tt><qualified-identifier></tt>
is called <em>relative</em>). If the specified region is not defined, it is
created. </p>
<p>The <span class="preprocessor">#region</span> directive is opaque for all macro
definitions made outside this region, i.e. no macros defined inside of other
regions or at the global scope are directly accessible from inside the opened
region. To access such macros these must be imported (see the <span class="preprocessor">#import</span>
directive) or must be referred to through it's qualified name. </p>
<p>Regions may be nested. </p>
<p>A region may be re-opened (i.e. a <span class="preprocessor">#region</span>
directive with the same name is found at the same scope), and macros from the
previous occurences of this region will be visible. </p>
<p>Region names and macro names of the same scope are stored into the same symbol
table. This implies, that at one scope there shall not be defined a region and
a macro with the same name.</p>
<p>Macros defined inside a nameless region may not be accessed from outside this
region. Further, from inside a nameless region it is not allowed to open an
enclosed region through an <em>absolute</em> name.</p>
<p>The argument of the <span class="preprocessor">#region</span> directive is
<strong>not</strong> subject to macro expansion before it is evaluated.</p>
<p>The following is a small code sample, which shows possible usages of preprocessor
regions.</p>
<pre> <span class="preprocessor">#define</span> A() 1
<span class="comment">/////////////////////////////////////</span>
<span class="preprocessor">#region</span> region_A
<span class="preprocessor"># define</span> B() 2
<span class="comment">/////////////////////////////////////</span>
<span class="preprocessor"># region</span> region_B
<span class="preprocessor"># define</span> C() 3
A() <span class="comment">// expands to: A()</span>
B() <span class="comment">// expands to: B()</span>
C() <span class="comment">// expands to: 3</span>
<span class="preprocessor"># endregion</span> <span class="comment">// region_B</span>
<span class="comment">/////////////////////////////////////</span>
A() <span class="comment">// expands to: A()</span>
B() <span class="comment">// expands to: 2</span>
C() <span class="comment">// expands to: C()</span>
region_B::C() <span class="comment">// expands to: 3</span>
::region_A::region_B::C() <span class="comment">// expands to: 3</span>
<span class="preprocessor">#endregion</span> <span class="comment">// region_A</span>
<span class="comment">/////////////////////////////////////</span>
A() <span class="comment">// expands to: 1</span>
B() <span class="comment">// expands to: B()</span>
region_A::B() <span class="comment">// expands to: 2</span>
::region_A::B() <span class="comment">// expands to: 2</span>
region_A::region_B::C() <span class="comment">// expands to: 3</span>
::region_A::region_B::C() <span class="comment">// expands to: 3</span>
<span class="preprocessor">#define</span> region_A ... <span class="comment">// error, name clash with region_A</span>
<span class="preprocessor">#region</span> A <span class="comment">// error, name clash with macro A</span>
<span class="preprocessor">#endregion</span>
</pre>
<h3>The #endregion directive</h3>
<h4>Syntax</h4>
<blockquote>
<p><tt>#endregion</tt></p>
</blockquote>
<p>The #endregion directive closes the last opened region. It is opaque for all
macros defined inside the closed region. Macros from defined inside this region
may be accessed from outside of this region only if imported (see the <span class="preprocessor">
#import</span> directive) or if used as qualified names specifying the region
and the macro name and if the region isn't unnamed.</p>
<p>The <span class="preprocessor">#region</span> and <span class="preprocessor">#endregion</span>
directives shall be balanced over the whole translation unit. Otherwise an error
is raised.</p>
<h3>The #import directive</h3>
<h4>Syntax</h4>
<blockquote>
<p><tt>#import <qualified-identifier> [, <qualified-identifier>
...]</tt></p>
</blockquote>
<blockquote>
<p>Where <tt><qualified-identifier></tt> is an optionally qualified name
defining the name of the region to open. The #import directive may specify
one or more comma separated qualified names.</p>
</blockquote>
<p>If the qualified identifier starts with an <tt>'::'</tt> the name is looked
up relative to the global scope (the <tt><qualified-identifier></tt> is
called <em>absolute</em>), if it starts with an identifier, the region is looked
up relative to the current open region (the <tt><qualified-identifier></tt>
is called <em>relative</em>). </p>
<p>If <tt><qualified-identifier></tt> refers to a macro, then the referenced
macro definition is <strong>copied</strong> into the current region, just if
it were defined here.</p>
<p>If <tt><qualified-identifier></tt> refers to a region, then</p>
<ul>
<li>all macro definitions of the referenced region are <strong>copied</strong>
into the current region, just if these were defined here.</li>
<li> all sub-regions of the referenced region are made available from the current
region, just if these were defined as direct sub-regions of the<br>
current region.</li>
</ul>
<p> Imported macros may be undefined with the <span class="preprocessor">#undef</span>
directive as usual. This removes the referenced macro from the current region,
but leaves it unchanged in the original region, where it was defined initially.<br>
<br>
The argument of the <span class="preprocessor">#import</span> directive is <strong>not</strong>
subject to macro expansion before it is evaluated. </p>
<h3>Changes to the #ifdef, #ifndef directives and the operator defined()</h3>
<p>To fully support macro regions, the <span class="preprocessor">#ifdef</span>
and <span class="preprocessor">#ifndef</span> directives and the <span class="preprocessor">operator
defined()</span> may be used with qualified identifiers as its arguments too.
Therefor the following sample is completely wellformed (curtesy to Paul Mensonides):</p>
<pre> <span class="preprocessor"># ifndef</span> ::CHAOS_PREPROCESSOR::chaos::WSTRINGIZE_HPP
<span class="preprocessor"># region</span> ::CHAOS_PREPROCESSOR::chaos
<span class="preprocessor">#</span>
<span class="preprocessor"># define</span> WSTRINGIZE_HPP
<span class="preprocessor">#</span>
<span class="preprocessor"># include</span> <span class="copyright"><chaos/experimental/cat.hpp></span>
<span class="preprocessor">#</span>
<span class="preprocessor">#</span> <span class="comment">// wstringize</span>
<span class="preprocessor">#</span>
<span class="preprocessor"># define</span> wstringize(...) \
chaos::primitive_wstringize(__VA_ARGS__) \
<span class="comment">/**/</span>
<span class="preprocessor">#</span>
<span class="preprocessor">#</span> <span class="comment">// primitive_wstringize</span>
<span class="preprocessor">#</span>
<span class="preprocessor"># define</span> primitive_wstringize(...) \
chaos::primitive_cat(L, #__VA_ARGS__) \
<span class="comment">/**/</span>
<span class="preprocessor">#</span>
<span class="preprocessor"># endregion</span>
<span class="preprocessor"># endif</span>
<span class="preprocessor"># import</span> ::CHAOS_PREPROCESSOR
chaos::wstringize(a,b,c) <span class="comment">// L"a,b,c"</span>
</pre>
<h2><a name="new_alternative_tokens"></a>New alternative tokens</h2>
<p>Vesa Karvonen recently suggested on the <a href="http://aspn.activestate.com/ASPN/Mail/Message/boost/1618972">Boost
mailing list</a> the following addition to the preprocessor, which is implemented
by <tt>Wave</tt> in C++0x mode.</p>
<p>Consider the following example:</p>
<pre> <span class="preprocessor">#define</span> ID(x) x
ID( ( )
ID( a , b )
ID( ) )</pre>
<p>The macro expansion of the above preprocessor code does not produce the intended
result: </p>
<pre> ( a , b )</pre>
<p>The basic idea is that the keywords <tt>__lparen__</tt>, <tt>__rparen__</tt>
and <tt>__comma__</tt> could be used in place of <span class="literal">'('</span>,
<span class="literal">')'</span> and <span class="literal">','</span>, respectively.
The <br>
above example would now become:</p>
<pre> <span class="preprocessor">#define</span> ID(x) x
ID( __lparen__ )
ID( a __comma__ b )
ID( __rparen__ )</pre>
<p>and it would expand into:</p>
<pre> __lparen__ a __comma__ b __rparen__</pre>
<p>which would be recognized in translation phases after macro replacement as
equivalent to the token sequence:</p>
<pre> ( a , b )</pre>
<p>This trivial extension makes it an order of magnitude easier to generate C++
code using the C preprocessor.</p>
<table border="0">
<tr>
<td width="10"></td>
<td width="30"><a href="index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_reference_inputpolicy.html"><img src="theme/l_arr.gif" width="20" height="19" border="0"></a></td>
<td width="20"><a href="wave_driver.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<hr size="1">
<p class="copyright">Copyright © 2003 Hartmut Kaiser<br>Copyright © 2003 Paul Mensonides<br>Copyright © 2003 Vesa Karvonen<br>
<br>
<font size="2">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. </font> </p>
<span class="updated">Last updated:
<!-- #BeginDate format:fcAm1m -->Monday, May 12, 2003 15:44<!-- #EndDate -->
</span>
<p> </p>
</body>
</html>