Просмотр исходного кода

added intgral constant expression guideleines

[SVN r9832]
John Maddock 25 лет назад
Родитель
Сommit
3b640b2c68
2 измененных файлов с 422 добавлено и 71 удалено
  1. 99 71
      more/index.htm
  2. 323 0
      more/integral_constant_guidelines.htm

+ 99 - 71
more/index.htm

@@ -1,97 +1,125 @@
 <html>
 
 <head>
-<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
-<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
 <meta name="ProgId" content="FrontPage.Editor.Document">
+<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
 <title>Boost More Information</title>
 </head>
 
 <body bgcolor="#FFFFFF" text="#000000">
 
-<table border="1" bgcolor="#007F7F" cellpadding="2">
-  <tr>
-    <td bgcolor="#FFFFFF"><img src="../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86"></td>
-    <td><a href="../index.htm"><font face="Arial" color="#FFFFFF"><big>Home</big></font></a></td>
-    <td><a href="../libs/libraries.htm"><font face="Arial" color="#FFFFFF"><big>Libraries</big></font></a></td>
-    <td><a href="../people/people.htm"><font face="Arial" color="#FFFFFF"><big>People</big></font></a></td>
-    <td><a href="faq.htm"><font face="Arial" color="#FFFFFF"><big>FAQ</big></font></a></td>
-    <td><a href="index.htm"><font face="Arial" color="#FFFFFF"><big>More</big></font></a></td>
-  </tr>
+<table border="1" cellpadding="2" bgcolor="#007F7F">
+    <tr>
+        <td bgcolor="#FFFFFF"><img src="../c++boost.gif"
+        alt="c++boost.gif (8819 bytes)" width="277" height="86"></td>
+        <td><a href="../index.htm"><font color="#FFFFFF" size="4"
+        face="Arial">Home</font></a></td>
+        <td><a href="../libs/libraries.htm"><font color="#FFFFFF"
+        size="4" face="Arial">Libraries</font></a></td>
+        <td><a href="../people/people.htm"><font color="#FFFFFF"
+        size="4" face="Arial">People</font></a></td>
+        <td><a href="faq.htm"><font color="#FFFFFF" size="4"
+        face="Arial">FAQ</font></a></td>
+        <td><a href="index.htm"><font color="#FFFFFF" size="4"
+        face="Arial">More</font></a></td>
+    </tr>
 </table>
+
 <h1>More Information</h1>
+
 <h2>Boost Policies</h2>
+
 <blockquote>
-  <p><b><a href="discussion_policy.htm">Mailing List Discussion Policy.</a></b>&nbsp;
-  What's acceptable and what isn't.</p>
-  <p><b><a href="lib_guide.htm">Library Requirements and Guidelines</a></b>.&nbsp;
-  Basic standards for those preparing a submission.</p>
-  <p><a href="test_policy.htm"><b>Test Policy and Protocols</b></a>.&nbsp; How
-  testing works at Boost.</p>
-  <p><a href="submission_process.htm"><b>Library Submission Process</b></a>.&nbsp;
-  How to submit a library to Boost.</p>
-  <p><b><a href="formal_review_process.htm">Library Formal Review Process</a></b>.
-  Including how to submit a review comment.</p>
-  <p><b><a href="header.htm">Header Policy</a></b>.&nbsp; Headers are where a
-  library contacts its users, so programming practices are particularly
-  important.</p>
-  <p><b><a href="imp_vars.htm">Implementation Variations</a></b>.&nbsp;
-  Sometimes one size fits all, sometimes it doesn't.&nbsp; This page deals with
-  the trade-offs.</p>
-  <p><b><a href="library_reuse.htm">Library Reuse</a></b>.&nbsp; Should Boost
-  libraries use other boost libraries?&nbsp; What about the C++ Standard
-  Library?&nbsp; It's another trade-off.</p>
-</blockquote>
-  <h2>Boost Whatever</h2>
-<blockquote>
-  <p> <a href="../status/compiler_status.html"><b>Compiler Status</b></a>&nbsp;&nbsp;
-  Describes what
-library works with which compiler.</p>
-<p> <a href="regression.html"><b>Internal Regression Test Suite</b></a>&nbsp;&nbsp;
-  Describes the tool for generating the compiler status tables
-<p> <a href="../libs/hdr_depend.html"><b>Header Dependencies</b></a>&nbsp;&nbsp;
-Describes what
-other headers each boost header includes.</p>
+    <p><a href="discussion_policy.htm"><b>Mailing List Discussion
+    Policy.</b></a>&nbsp; What's acceptable and what isn't.</p>
+    <p><a href="lib_guide.htm"><b>Library Requirements and
+    Guidelines</b></a>.&nbsp; Basic standards for those preparing
+    a submission.</p>
+    <p><a href="test_policy.htm"><b>Test Policy and Protocols</b></a>.&nbsp;
+    How testing works at Boost.</p>
+    <p><a href="submission_process.htm"><b>Library Submission
+    Process</b></a>.&nbsp; How to submit a library to Boost.</p>
+    <p><a href="formal_review_process.htm"><b>Library Formal
+    Review Process</b></a>. Including how to submit a review
+    comment.</p>
+    <p><a href="header.htm"><b>Header Policy</b></a>.&nbsp;
+    Headers are where a library contacts its users, so
+    programming practices are particularly important.</p>
+    <p><a href="imp_vars.htm"><b>Implementation Variations</b></a>.&nbsp;
+    Sometimes one size fits all, sometimes it doesn't.&nbsp; This
+    page deals with the trade-offs.</p>
+    <p><a href="library_reuse.htm"><b>Library Reuse</b></a>.&nbsp;
+    Should Boost libraries use other boost libraries?&nbsp; What
+    about the C++ Standard Library?&nbsp; It's another trade-off.</p>
 </blockquote>
-<h2>Articles and Papers</h2>
-<blockquote>
-
-  <p><a href="error_handling.html"><b>Error and Exception Handling</b></a>
-  describes approaches to errors and exceptions by <a
-  href="../people/dave_abrahams.htm">David Abrahams</a>.
-
-  <p><b><a href="count_bdy.htm">Counted Body Techniques</a></b> by <a href="../people/kevlin_henney.htm">Kevlin
-  Henney</a> is must reading for those interested in reference counting, a
-  widely used object management idiom.&nbsp; Originally published in <a href="http://www.accu.org/c++sig/public/Overload.html">Overload</a>
-  magazine.</p>
-
-  <p><b><a href="generic_programming.html">Generic Programming
-  Techniques</a></b> by <a href="../people/dave_abrahams.htm">David Abrahams</a>
-  and <a href="../people/jeremy_siek.htm">Jeremy Siek</a>describe some of the
-  techniques used in Boost libraries.</p>
 
-  <p><b><a href="feature_model_diagrams.htm">Feature Model Diagrams in text and
-  HTML</a></b> describes how to represent feature model diagrams in text form.</p>
+<h2>Boost Whatever</h2>
 
-  <p><b><a href="borland_cpp.html">Portability Hints: Borland C++ 5.5.1</a></b>
-  describes Borland C++ portability issues, with suggested workarounds.</p>
+<blockquote>
+    <p><a href="../status/compiler_status.html"><b>Compiler
+    Status</b></a>&nbsp;&nbsp; Describes what library works with
+    which compiler.</p>
+    <p><a href="regression.html"><b>Internal Regression Test
+    Suite</b></a>&nbsp;&nbsp; Describes the tool for generating
+    the compiler status tables </p>
+    <p><a href="../libs/hdr_depend.html"><b>Header Dependencies</b></a>&nbsp;&nbsp;
+    Describes what other headers each boost header includes.</p>
+</blockquote>
 
-  <p><a href="microsoft_vcpp.html"><b>Portability Hints: Microsoft VC++ 6.0 SP4</b></a>
-  describes Microsoft C++ portability issues, with suggested workarounds.</p>
+<h2>Articles and Papers</h2>
 
+<blockquote>
+    <p><a href="error_handling.html"><b>Error and Exception
+    Handling</b></a> describes approaches to errors and
+    exceptions by <a href="../people/dave_abrahams.htm">David
+    Abrahams</a>. </p>
+    <p><a href="count_bdy.htm"><b>Counted Body Techniques</b></a>
+    by <a href="../people/kevlin_henney.htm">Kevlin Henney</a> is
+    must reading for those interested in reference counting, a
+    widely used object management idiom.&nbsp; Originally
+    published in <a
+    href="http://www.accu.org/c++sig/public/Overload.html">Overload</a>
+    magazine.</p>
+    <p><a href="generic_programming.html"><b>Generic Programming
+    Techniques</b></a> by <a href="../people/dave_abrahams.htm">David
+    Abrahams</a> and <a href="../people/jeremy_siek.htm">Jeremy
+    Siek</a>describe some of the techniques used in Boost
+    libraries.</p>
+    <p><a href="feature_model_diagrams.htm"><b>Feature Model
+    Diagrams in text and HTML</b></a> describes how to represent
+    feature model diagrams in text form.</p>
+    <p><a href="borland_cpp.html"><b>Portability Hints: Borland C++
+    5.5.1</b></a> describes Borland C++ portability issues, with
+    suggested workarounds.</p>
+    <p><a href="microsoft_vcpp.html"><b>Portability Hints:
+    Microsoft VC++ 6.0 SP4</b></a> describes Microsoft C++
+    portability issues, with suggested workarounds.</p>
+    <p><a href="integral_constant_guidelines.htm"><strong>Coding
+    Guidelines for Integral Constant Expressions</strong></a>
+    describes how to work through the maze of compiler related
+    bugs surrounding this tricky topic.</p>
 </blockquote>
+
 <h2>Links</h2>
+
 <blockquote>
-  <p>The C++ Standard (ISO/IEC 14882) is available online as a PDF file from the
-  <a href="http://www.ansi.org">ANSI</a> (American National Standards Institute)
-  Electronic Standards Store.&nbsp; The price is $US 18.00. The document is
-  certainly not a tutorial, but is interesting to those who care about the
-  precise specification of the language and the standard library.</p>
+    <p>The C++ Standard (ISO/IEC 14882) is available online as a
+    PDF file from the <a href="http://www.ansi.org">ANSI</a> (American
+    National Standards Institute) Electronic Standards Store.&nbsp;
+    The price is $US 18.00. The document is certainly not a
+    tutorial, but is interesting to those who care about the
+    precise specification of the language and the standard
+    library.</p>
 </blockquote>
-  <p>&nbsp;</p>
+
+<p>&nbsp;</p>
+
 <hr>
-<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->12 February, 2001<!--webbot bot="Timestamp" endspan i-checksum="40399" --></p>
 
+<p>Revised <!--webbot bot="Timestamp" startspan s-type="EDITED"
+s-format="%d %B, %Y" -->17 April, 2001<!--webbot bot="Timestamp"
+i-checksum="29819" endspan --></p>
 </body>
-
 </html>

+ 323 - 0
more/integral_constant_guidelines.htm

@@ -0,0 +1,323 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<meta name="Template"
+content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
+<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
+<title></title>
+</head>
+
+<body bgcolor="#FFFFFF" link="#0000FF" vlink="#800080">
+
+<h2 align="center">Coding Guidelines for Integral Constant
+Expressions</h2>
+
+<p>Integral Constant Expressions are used in many places in C++;
+as array bounds, as bit-field lengths, as enumerator
+initialisers, and as arguments to non-type template parameters.
+However many compilers have problems handling integral constant
+expressions; as a result of this, programming using non-type
+template parameters in particular can be fraught with difficulty,
+often leading to the incorrect assumption that non-type template
+parameters are unsupported by a particular compiler. This short
+article is designed to provide a set of guidelines and
+workarounds that, if followed, will allow integral constant
+expressions to be used in a manner portable to all the compilers
+currently supported by boost. Although this article is mainly
+targeted at boost library authors, it may also be useful for
+users who want to understand why boost code is written in a
+particular way, or who want to write portable code themselves.</p>
+
+<h3>What is an Integral Constant Expression?</h3>
+
+<p>Integral constant expressions are described in section 5.19 of
+the standard, and are sometimes referred to as &quot;compile time
+constants&quot;. An integral constant expression can be one of
+the following:</p>
+
+<ol>
+    <li>A literal integral value, for example 0u or 3L.</li>
+    <li>An enumerator value.</li>
+    <li>Global integral constants, for example: <font
+        face="Courier New"><code><br>
+        </code></font><code>const int my_INTEGRAL_CONSTANT = 3;</code></li>
+    <li>Static member constants, for example: <br>
+        <code>struct myclass<br>
+        { static const int value = 0; };</code></li>
+    <li>Member enumerator values, for example:<br>
+        <code>struct myclass<br>
+        { enum{ value = 0 }; };</code></li>
+    <li>Non-type template parameters of integral or enumerator
+        type.</li>
+    <li>The result of a <code>sizeof</code> expression, for
+        example:<br>
+        <code>sizeof(foo(a, b, c))</code></li>
+    <li>The result of a <code>static_cast</code>, where the
+        target type is an integral or enumerator type, and the
+        argument is either another integral constant expression,
+        or a floating-point literal.</li>
+    <li>The result of applying a binary operator to two integral
+        constant expressions: <br>
+        <code>INTEGRAL_CONSTANT1 op INTEGRAL_CONSTANT2 <br>
+        p</code>rovided that the operator is not an assignment
+        operator, or comma operator.</li>
+    <li>The result of applying a unary operator to an integral
+        constant expression: <br>
+        <code>op INTEGRAL_CONSTANT1<br>
+        </code>provided that the operator is not the increment or
+        decrement operator.</li>
+</ol>
+
+<p>&nbsp;</p>
+
+<h3>Coding Guidelines</h3>
+
+<p>The following guidelines are declared in no particular order (in
+other words you need to obey all of them - sorry!), and may also
+be incomplete, more guidelines may be added as compilers change
+and/or more problems are encountered.</p>
+
+<p><b><i>When declaring constants that are class members always
+use the macro BOOST_STATIC_CONSTANT.</i></b></p>
+
+<pre>template &lt;class T&gt;
+struct myclass
+{
+   BOOST_STATIC_CONSTANT(int, value = sizeof(T));
+};</pre>
+
+<p>Rationale: not all compilers support inline initialisation of
+member constants, others treat member enumerators in strange ways
+(they're not always treated as integral constant expressions).
+The BOOST_STATIC_CONSTANT macro uses the most appropriate method
+for the compiler in question.</p>
+
+<p><b><i>Don't declare integral constant expressions whose type
+is wider than int.</i></b></p>
+
+<p>Rationale: while in theory all integral types are usable in
+integral constant expressions, in practice many compilers limit
+integral constant expressions to types no wider than <b>int</b>.</p>
+
+<p><b><i>Don't use logical operators in integral constant
+expressions; use template meta-programming instead.</i></b></p>
+
+<p>The header &lt;boost/type_traits/ice.hpp&gt; contains a number
+of workaround templates, that fulfil the role of logical
+operators, for example instead of:</p>
+
+<p><code>INTEGRAL_CONSTANT1 | INTEGRAL_CONSTANT2</code></p>
+
+<p>Use:</p>
+
+<p><code>::boost::type_traits::ice_or&lt;INTEGRAL_CONSTANT1,INTEGRAL_CONSTANT2&gt;::value</code></p>
+
+<p>Rationale: A number of compilers (particularly the Borland and
+Microsoft compilers), tend to not to recognise integral constant
+expressions involving logical operators as genuine integral
+constant expressions. The problem generally only shows up when
+the integral constant expression is nested deep inside template
+code, and is hard to reproduce and diagnose.</p>
+
+<p><b><i>Don't use any operators in an integral constant
+expression used as a non-type template parameter</i></b></p>
+
+<p>Rather than:</p>
+
+<p><code>typedef myclass&lt;INTEGRAL_CONSTANT1 ==
+INTEGRAL_CONSTANT2&gt; mytypedef;</code></p>
+
+<p>Use:</p>
+
+<p><code>typedef myclass&lt; some_symbol&gt; mytypedef;</code></p>
+
+<p>Where <code>some_symbol</code> is the symbolic name of a an
+integral constant expression whose value is <code>(INTEGRAL_CONSTANT1
+== INTEGRAL_CONSTANT2).</code></p>
+
+<p>Rationale: the older EDG based compilers (some of which are
+used in the most recent version of that platform's compiler),
+don't recognise expressions containing operators as non-type
+template parameters, even though such expressions can be used as
+integral constant expressions elsewhere.</p>
+
+<p><b><i>Always use a fully qualified name to refer to an
+integral constant expression.</i></b></p>
+
+<p>For example:</p>
+
+<pre><code>typedef</code> myclass&lt; ::boost::is_integral&lt;some_type&gt;::value&gt; mytypedef;</pre>
+
+<p>Rationale: at least one compiler (Borland's), doesn't
+recognise the name of a constant as an integral constant
+expression unless the name is fully qualified (which is to say it
+starts with ::).</p>
+
+<p><b><i>Always leave a space after a '&lt;' and before '::'</i></b></p>
+
+<p>For example:</p>
+
+<pre><code>typedef</code> myclass&lt; ::boost::is_integral&lt;some_type&gt;::value&gt; mytypedef;
+                ^
+                ensure there is space here!</pre>
+
+<p>Rationale: &lt;: is a legal digraph in it's own right, so &lt;::
+is interpreted as the same as [:.</p>
+
+<p><b><i>Don't use local names as integral constant expressions</i></b></p>
+
+<p>Example:</p>
+
+<pre>template &lt;class T&gt;
+struct foobar
+{
+   BOOST_STATIC_CONSTANT(int, temp = computed_value);
+   typedef myclass&lt;temp&gt; mytypedef;  // error
+};</pre>
+
+<p>Rationale: At least one compiler (Borland's) doesn't accept
+this.</p>
+
+<p>Although it is possible to fix this by using:</p>
+
+<pre>template &lt;class T&gt;
+struct foobar
+{
+   BOOST_STATIC_CONSTANT(int, temp = computed_value);
+   typedef foobar self_type;
+   typedef myclass&lt;(self_type::temp)&gt; mytypedef;  // OK
+};</pre>
+
+<p>This breaks at least one other compiler (VC6), it is better to
+move the integral constant expression computation out into a
+separate traits class:</p>
+
+<pre>template &lt;class T&gt;
+struct foobar_helper
+{
+   BOOST_STATIC_CONSTANT(int, temp = computed_value);
+};
+
+template &lt;class T&gt;
+struct foobar
+{
+   typedef myclass&lt; ::foobar_helper&lt;T&gt;::value&gt; mytypedef;  // OK
+};</pre>
+
+<p><b><i>Don't use dependent default parameters for non-type
+template parameters.</i></b></p>
+
+<p>For example:</p>
+
+<pre>template &lt;class T, int I = ::boost::is_integral&lt;T&gt;::value&gt;  // Error can't deduce value of I in some cases.
+struct foobar;</pre>
+
+<p>Rationale: this kind of usage fails for Borland C++. Note that
+this is only an issue where the default value is dependent upon a
+previous template parameter, for example the following is fine:</p>
+
+<pre>template &lt;class T, int I = 3&gt;  // OK, default value is not dependent
+struct foobar;</pre>
+
+<p>&nbsp;</p>
+
+<h3>Unresolved Issues</h3>
+
+<p>The following issues are either unresolved or have fixes that
+are compiler specific, and/or break one or more of the coding
+guidelines.</p>
+
+<p><b><i>Be careful of numeric_limits</i></b></p>
+
+<p>There are three issues here:</p>
+
+<ol>
+    <li>The header &lt;limits&gt; may be absent - it is
+        recommended that you never include &lt;limits&gt;
+        directly but use &lt;boost/pending/limits.hpp&gt; instead.
+        This header includes the &quot;real&quot; &lt;limits&gt;
+        header if it is available, otherwise it supplies it's own
+        std::numeric_limits definition. Boost also defines the
+        macro BOOST_NO_LIMITS if &lt;limits&gt; is absent.</li>
+    <li>The implementation of std::numeric_limits may be defined
+        in such a way that its static-const members may not be
+        usable as integral constant expressions. This contradicts
+        the standard but seems to be a bug that affects at least
+        two standard library vendors; boost defines
+        BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS in &lt;boost/config.hpp&gt;
+        when this is the case.</li>
+    <li>There is a strange bug in VC6, where the members of std::numeric_limits
+        can be &quot;prematurely evaluated&quot; in template
+        code, for example:</li>
+</ol>
+
+<pre>template &lt;class T&gt;
+struct limits_test
+{
+   BOOST_STATIC_ASSERT(::std::numeric_limits&lt;T&gt;::is_specialized);
+};</pre>
+
+<p>This code fails to compile with VC6 even though no instances
+of the template are ever created; for some bizarre reason <code>::std::numeric_limits&lt;T&gt;::is_specialized
+</code>always evaluates to false, irrespective of what the
+template parameter T is. The problem seems to be confined to
+expressions which depend on std::numeric_limts: for example if
+you replace <code>::std::numeric_limits&lt;T&gt;::is_specialized</code>
+with <code>::boost::is_arithmetic&lt;T&gt;::value</code>, then
+everything is fine. The following workaround also works but
+conflicts with the coding guidelines:</p>
+
+<pre>template &lt;class T&gt;
+struct limits_test
+{
+   BOOST_STATIC_CONSTANT(bool, check = ::std::numeric_limits&lt;T&gt;::is_specialized);
+   BOOST_STATIC_ASSERT(check);
+};</pre>
+
+<p>So it is probably best to resort to something like this:</p>
+
+<pre>template &lt;class T&gt;
+struct limits_test
+{
+#ifdef BOOST_MSVC
+   BOOST_STATIC_CONSTANT(bool, check = ::std::numeric_limits&lt;T&gt;::is_specialized);
+   BOOST_STATIC_ASSERT(check);
+#else
+   BOOST_STATIC_ASSERT(::std::numeric_limits&lt;T&gt;::is_specialized);
+#endif
+};</pre>
+
+<p><b><i>Be careful how you use the sizeof operator</i></b></p>
+
+<p>As far as I can tell, all compilers treat sizeof expressions
+correctly when the argument is the name of a type (or a template-id),
+however problems can occur if:</p>
+
+<ol>
+    <li>The argument is the name of a member-variable, or a local
+        variable (code may not compile with VC6).</li>
+    <li>The argument is an expression which involves the creation
+        of a temporary (code will not compile with Borland C++).</li>
+    <li>The argument is an expression involving an overloaded
+        function call (code compiles but the result is a garbage
+        value with Metroworks C++).</li>
+</ol>
+
+<p><b><i>Don't use boost::is_convertible unless you have to</i></b></p>
+
+<p>Since is_convertible is implemented in terms of the sizeof
+operator, it consistently gives the wrong value when used with
+the Metroworks compiler, and may not compile with the Borland's
+compiler (depending upon the template arguments used).</p>
+
+<hr>
+
+<p>Copyright Dr John Maddock 2001, all rights reserved.</p>
+
+<p>&nbsp;</p>
+
+<p>&nbsp;</p>
+</body>
+</html>

粤ICP备19079148号