broken-integral-constant.html 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4. <!-- Copyright Aleksey Gurtovoy 2006. Distributed under the Boost -->
  5. <!-- Software License, Version 1.0. (See accompanying -->
  6. <!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
  7. <head>
  8. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  9. <meta name="generator" content="Docutils 0.3.6: http://docutils.sourceforge.net/" />
  10. <title>THE BOOST MPL LIBRARY: Broken Integral Constant Expressions</title>
  11. <link rel="stylesheet" href="../style.css" type="text/css" />
  12. </head>
  13. <body class="docframe">
  14. <table class="header"><tr class="header"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./portability.html" class="navigation-link">Prev</a>&nbsp;<a href="./incomplete-support-for.html" class="navigation-link">Next</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group">Back&nbsp;<a href="./incomplete-support-for.html" class="navigation-link">Along</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group"><a href="./portability.html" class="navigation-link">Up</a>&nbsp;<a href="../index.html" class="navigation-link">Home</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group"><a href="./tutorial_toc.html" class="navigation-link">Full TOC</a></span></td>
  15. <td class="header-group page-location"><a href="../index.html" class="navigation-link">Front Page</a> / <a href="./technical-details.html" class="navigation-link">Technical Details</a> / <a href="./portability.html" class="navigation-link">Portability</a> / <a href="./broken-integral-constant.html" class="navigation-link">Broken Integral Constant Expressions</a></td>
  16. </tr></table><div class="header-separator"></div>
  17. <div class="section" id="broken-integral-constant">
  18. <h1><a class="toc-backref" href="./portability.html#id74" name="broken-integral-constant">Broken Integral Constant Expressions</a></h1>
  19. <p>This is probably the most surprising of the portability issues
  20. we're going to discuss, not least because for many C++ programmers, their everyday
  21. experience seems to indicate no problems in this area whatsoever. After all,
  22. integer compile-time computations along the lines of:</p>
  23. <pre class="literal-block">
  24. enum flags {
  25. flag1 = (1 &lt;&lt; 0)
  26. , flag2 = (1 &lt;&lt; 1)
  27. , flag3 = (1 &lt;&lt; 2)
  28. ...
  29. };
  30. </pre>
  31. <p>are <em>very</em> commonplace in C++, and there is hardly a compiler out
  32. there that cannot handle this correctly. While arithmetic by
  33. itself is indeed rarely problematic, when you are trying to mix it
  34. with templates on certain deficient compilers, all kinds of new
  35. issues arise. Fortunately, as with the rest of the portability
  36. issues we're discussing here, the problem fades into past as new
  37. compiler versions are released. The majority of most recent
  38. compilers of many vendors are already free from these issues.</p>
  39. <div class="section" id="the-problem">
  40. <h2><a name="the-problem">The Problem</a></h2>
  41. <p>The problem is in fact multi-faceted; there are a number of
  42. different subissues. Some are present in one set of compilers,
  43. some are in another, and it's not uncommon for a code that works
  44. for one compiler to break another one and vice-versa. If this
  45. sounds like a maintenance nightmare to you, it is! If you are
  46. interested in the specific list of issues, please refer to John
  47. Maddock's excellent &quot;<a class="reference" href="http://www.boost.org/more/int_const_guidelines.htm" target="_top">Coding Guidelines for Integral Constant
  48. Expressions</a>&quot; summary. For the purpose of our discission here, it
  49. is sufficient to say that if your code has to work on one of the
  50. compilers listed as problematic in this area, you can safely assume
  51. that if you decide to fight them on a case-by-case basis, chances
  52. are that you won't be able to maintain your sanity for very long.</p>
  53. </div>
  54. <div class="section" id="the-symptoms">
  55. <h2><a name="the-symptoms">The Symptoms</a></h2>
  56. <p>On the positive side, when you have an issue with integral
  57. arithmetic, the diagnostics are almost always straightforward:
  58. usually the error message refers you to the exact place in the code
  59. that is causing problems, and the essence of issue is obvious from
  60. the error's text, or it becomes obvious once you've encountered the
  61. same error a couple of times. For instance, if we throw this
  62. well-formed fragment at MSVC 7.1 (otherwise an excellent compiler!)</p>
  63. <pre class="literal-block">
  64. void value();
  65. // compares two Integral Constants
  66. template&lt; typename N1, typename N2 &gt; struct less
  67. : bool_&lt; (N1::value &lt; N2::value) &gt; // line #8
  68. {
  69. };
  70. </pre>
  71. <p>we get:</p>
  72. <pre class="literal-block">
  73. portability.cpp(8) : warning C4346: 'N2::value' : dependent name is not a type
  74. prefix with 'typename' to indicate a type
  75. portability.cpp(10) : see reference to class template instantiation 'less&lt;N1,N2&gt;' being compiled
  76. portability.cpp(8) : error C2143: syntax error : missing ',' before ')'
  77. portability.cpp(9) : error C2143: syntax error : missing ';' before '{'
  78. portability.cpp(10) : error C2143: syntax error : missing ';' before '}'
  79. portability.cpp(10) : fatal error C1004: unexpected end of file found
  80. </pre>
  81. <p>The errors themselves are far from being ideal, but at least we are
  82. pointed at the correct line and even the correct part of the
  83. line. The above basically reads as &quot;something's wrong between the
  84. parentheses&quot;, and that plus the &quot;syntax error&quot; part is usually
  85. enough of the clue.</p>
  86. </div>
  87. <div class="section" id="the-solution">
  88. <h2><a name="the-solution">The Solution</a></h2>
  89. <p>Despite the fact the problems are so numerous and multi-faceted and
  90. the workarounds are conflicting, the problems can be hidden
  91. reliably beneath a library abstraction layer. The underlaying idea
  92. is very simple: we can always wrap the constants in types and pass
  93. those around. Then all that is left is to implement algebraic
  94. metafunctions that operate on such wrappers, once, and we are home
  95. safe.</p>
  96. <p>If this sounds familiar to you, probably it's because you have
  97. already took a look at the MPL and know that the approach we just
  98. described is in fact <em>the</em> standard way of doing arithmetic in the
  99. library. Although it's motivated by more general observations,
  100. this fact comes very handy for the library users that care about
  101. portability of their numerically-heavy metaprograms. The MPL
  102. primitives are already there, and more importantly, they already
  103. implement the necessary workarounds, so your numeric code just
  104. works. In fact, if you stay within the library's type-wrapper
  105. idioms, these particular problems never &quot;leak&quot; out of its
  106. abstraction layer.</p>
  107. <p>On a final note, there is a price of avoiding built-in arithmetics
  108. altogether, namely decreased readability and, on some compilers,
  109. increased compile-time overhead. Still, in majority of cases, the
  110. benefits of type-based arithmetics overweight its small
  111. shortcomings.</p>
  112. </div>
  113. </div>
  114. <div class="footer-separator"></div>
  115. <table class="footer"><tr class="footer"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./portability.html" class="navigation-link">Prev</a>&nbsp;<a href="./incomplete-support-for.html" class="navigation-link">Next</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group">Back&nbsp;<a href="./incomplete-support-for.html" class="navigation-link">Along</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group"><a href="./portability.html" class="navigation-link">Up</a>&nbsp;<a href="../index.html" class="navigation-link">Home</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group"><a href="./tutorial_toc.html" class="navigation-link">Full TOC</a></span></td>
  116. </tr></table></body>
  117. </html>