diff options
author | John Maddock <john@johnmaddock.co.uk> | 2001-04-18 11:27:48 +0000 |
---|---|---|
committer | John Maddock <john@johnmaddock.co.uk> | 2001-04-18 11:27:48 +0000 |
commit | 3b640b2c68054093e1627abd707d33a693301047 (patch) | |
tree | d2b77da325f4bdd95322c03ab95feb534568020a /more | |
parent | ca8614dd160a309c39fcc3bd16635861539d95cf (diff) | |
download | boost-3b640b2c68054093e1627abd707d33a693301047.tar.gz |
added intgral constant expression guideleines
[SVN r9832]
Diffstat (limited to 'more')
-rw-r--r-- | more/index.htm | 170 | ||||
-rw-r--r-- | more/integral_constant_guidelines.htm | 323 |
2 files changed, 422 insertions, 71 deletions
diff --git a/more/index.htm b/more/index.htm index 71367b1166..4314c8199e 100644 --- a/more/index.htm +++ b/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> - What's acceptable and what isn't.</p> - <p><b><a href="lib_guide.htm">Library Requirements and Guidelines</a></b>. - Basic standards for those preparing a submission.</p> - <p><a href="test_policy.htm"><b>Test Policy and Protocols</b></a>. How - testing works at Boost.</p> - <p><a href="submission_process.htm"><b>Library Submission Process</b></a>. - 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>. 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>. - Sometimes one size fits all, sometimes it doesn't. This page deals with - the trade-offs.</p> - <p><b><a href="library_reuse.htm">Library Reuse</a></b>. Should Boost - libraries use other boost libraries? What about the C++ Standard - Library? It's another trade-off.</p> -</blockquote> - <h2>Boost Whatever</h2> -<blockquote> - <p> <a href="../status/compiler_status.html"><b>Compiler Status</b></a> - Describes what -library works with which compiler.</p> -<p> <a href="regression.html"><b>Internal Regression Test Suite</b></a> - Describes the tool for generating the compiler status tables -<p> <a href="../libs/hdr_depend.html"><b>Header Dependencies</b></a> -Describes what -other headers each boost header includes.</p> + <p><a href="discussion_policy.htm"><b>Mailing List Discussion + Policy.</b></a> What's acceptable and what isn't.</p> + <p><a href="lib_guide.htm"><b>Library Requirements and + Guidelines</b></a>. Basic standards for those preparing + a submission.</p> + <p><a href="test_policy.htm"><b>Test Policy and Protocols</b></a>. + How testing works at Boost.</p> + <p><a href="submission_process.htm"><b>Library Submission + Process</b></a>. 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>. + 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>. + Sometimes one size fits all, sometimes it doesn't. This + page deals with the trade-offs.</p> + <p><a href="library_reuse.htm"><b>Library Reuse</b></a>. + Should Boost libraries use other boost libraries? What + about the C++ Standard Library? 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. 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> Describes what library works with + which compiler.</p> + <p><a href="regression.html"><b>Internal Regression Test + Suite</b></a> Describes the tool for generating + the compiler status tables </p> + <p><a href="../libs/hdr_depend.html"><b>Header Dependencies</b></a> + 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. 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. 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. + 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> </p> + +<p> </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> diff --git a/more/integral_constant_guidelines.htm b/more/integral_constant_guidelines.htm new file mode 100644 index 0000000000..a0e7d499ab --- /dev/null +++ b/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 "compile time +constants". 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> </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 <class T> +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 <boost/type_traits/ice.hpp> 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<INTEGRAL_CONSTANT1,INTEGRAL_CONSTANT2>::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<INTEGRAL_CONSTANT1 == +INTEGRAL_CONSTANT2> mytypedef;</code></p> + +<p>Use:</p> + +<p><code>typedef myclass< some_symbol> 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< ::boost::is_integral<some_type>::value> 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 '<' and before '::'</i></b></p> + +<p>For example:</p> + +<pre><code>typedef</code> myclass< ::boost::is_integral<some_type>::value> mytypedef; + ^ + ensure there is space here!</pre> + +<p>Rationale: <: is a legal digraph in it's own right, so <:: +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 <class T> +struct foobar +{ + BOOST_STATIC_CONSTANT(int, temp = computed_value); + typedef myclass<temp> 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 <class T> +struct foobar +{ + BOOST_STATIC_CONSTANT(int, temp = computed_value); + typedef foobar self_type; + typedef myclass<(self_type::temp)> 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 <class T> +struct foobar_helper +{ + BOOST_STATIC_CONSTANT(int, temp = computed_value); +}; + +template <class T> +struct foobar +{ + typedef myclass< ::foobar_helper<T>::value> 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 <class T, int I = ::boost::is_integral<T>::value> // 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 <class T, int I = 3> // OK, default value is not dependent +struct foobar;</pre> + +<p> </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 <limits> may be absent - it is + recommended that you never include <limits> + directly but use <boost/pending/limits.hpp> instead. + This header includes the "real" <limits> + header if it is available, otherwise it supplies it's own + std::numeric_limits definition. Boost also defines the + macro BOOST_NO_LIMITS if <limits> 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 <boost/config.hpp> + when this is the case.</li> + <li>There is a strange bug in VC6, where the members of std::numeric_limits + can be "prematurely evaluated" in template + code, for example:</li> +</ol> + +<pre>template <class T> +struct limits_test +{ + BOOST_STATIC_ASSERT(::std::numeric_limits<T>::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<T>::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<T>::is_specialized</code> +with <code>::boost::is_arithmetic<T>::value</code>, then +everything is fine. The following workaround also works but +conflicts with the coding guidelines:</p> + +<pre>template <class T> +struct limits_test +{ + BOOST_STATIC_CONSTANT(bool, check = ::std::numeric_limits<T>::is_specialized); + BOOST_STATIC_ASSERT(check); +};</pre> + +<p>So it is probably best to resort to something like this:</p> + +<pre>template <class T> +struct limits_test +{ +#ifdef BOOST_MSVC + BOOST_STATIC_CONSTANT(bool, check = ::std::numeric_limits<T>::is_specialized); + BOOST_STATIC_ASSERT(check); +#else + BOOST_STATIC_ASSERT(::std::numeric_limits<T>::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> </p> + +<p> </p> +</body> +</html> |