eti.html 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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: ETI</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="./incomplete-support-for.html" class="navigation-link">Prev</a>&nbsp;<a href="./resources.html" class="navigation-link">Next</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group"><a href="./incomplete-support-for.html" class="navigation-link">Back</a>&nbsp;Along</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="./eti.html" class="navigation-link">ETI</a></td>
  16. </tr></table><div class="header-separator"></div>
  17. <div class="section" id="eti">
  18. <h1><a class="toc-backref" href="./portability.html#id76" name="eti">ETI</a></h1>
  19. <p>In context of C++ template problems, ETI is an abbreviation for &quot;Early
  20. Template Instantiation&quot; — a Microsoft Visual C++ - specific issue that
  21. has been a barrier to any serious work with templates on this platform until
  22. Microsoft developers fixed it in Visual C++ 7.1 (2003 .NET). Although the
  23. problem is relatively easy to work around if the right techniques
  24. are applied systematically through the codebase, the approach is definitely
  25. tedious and time-consuming. So, if one day you discover that you are spending
  26. too much time dealing with the issue, consider upgrading to the
  27. newer version of the compiler. In fact, seriously consider it regardless.
  28. The benefits of saved time, money and frustration are well worth the price.</p>
  29. <div class="section" id="eti-the-problem">
  30. <h2><a name="eti-the-problem">The Problem</a></h2>
  31. <p>Here is a short demonstration of the issue with MSVC 6.x:</p>
  32. <pre class="literal-block">
  33. template&lt; typename F, typename T &gt; struct apply1
  34. {
  35. typedef typename F::template apply&lt;T&gt;::type type;
  36. };
  37. </pre>
  38. <p>Trying to compiling this innocent-looking code, we get:</p>
  39. <pre class="literal-block">
  40. portability.cpp(4) : error C2903: 'apply' : symbol is neither a class template
  41. nor a function template
  42. portability.cpp(5) : see reference to class template instantiation
  43. 'apply1&lt;F,T&gt;' being compiled
  44. portability.cpp(4) : error C2143: syntax error : missing ',' before '&lt;'
  45. portability.cpp(5) : see reference to class template instantiation
  46. 'apply1&lt;F,T&gt;' being compiled
  47. portability.cpp(4) : error C2059: syntax error : '&lt;'
  48. portability.cpp(5) : see reference to class template instantiation
  49. 'apply1&lt;F,T&gt;' being compiled
  50. </pre>
  51. <p>The &quot;symbol is neither a class template nor a function template&quot; part of the
  52. diagnostics is actually often an indication of ETI-related problems. Another
  53. typical error message usually says something about nested type such-and-such
  54. not being a member of a global namespace.</p>
  55. <p>Both cases are two sides of the same compiler bug, which we call
  56. &quot;Early template instantiation&quot;: the compiler, for internal
  57. purposes, in order to process class template definitions,
  58. instantiates class templates with dummy template parameters
  59. (<tt class="literal"><span class="pre">int</span></tt>'s). That can happen both during parsing of template
  60. definitions (and such errors are most easy to identify and fix —
  61. the template definition itself just doesn't compile; the example
  62. above falls into this category), or later during template
  63. instantiation, and these one are hard to detect — the bug will
  64. only be triggered in some particular context.</p>
  65. <!-- namespace-scope: nested templates are immune? -->
  66. <p>ETI is always performed during parsing of the namespace-scope
  67. template definition, which basically means that any template
  68. definition that is rendered invalid by substituting its template
  69. parameters by <tt class="literal"><span class="pre">int</span></tt>s might not compile, as it happened with our
  70. example:</p>
  71. <pre class="literal-block">
  72. template&lt; typename F, typename T &gt; struct apply1
  73. {
  74. // typedef typename F::template apply&lt;T&gt;::type type;
  75. // ETI generates this:
  76. typedef typename int::template apply&lt;int&gt;::type type;
  77. };
  78. </pre>
  79. <p>If you compile this, you'll get <em>exactly</em> the same diagnostics as we've just seen.</p>
  80. <p>Note that we've said &quot;might not compile&quot;, because... well, the short answer is,
  81. &quot;it depends&quot;. We haven't analyzed things to the point that we could tell you the
  82. exact condition when ETI leads to an error and when it doesn't, but
  83. that's not very important anyway — if it's an error, you just fix it (we'll show you how
  84. in a second), and if it's not, then you leave things as is. If one day the
  85. potential issue turns into a real one, then you apply the workaround we are about
  86. to give you.</p>
  87. </div>
  88. <div class="section" id="eti-the-symptoms">
  89. <h2><a name="eti-the-symptoms">The Symptoms</a></h2>
  90. <p>We've already looked at the typical diagnostics, so we won't repeat
  91. ourselves. Instead we'll
  92. just mention that many MSVC's INTERNAL COMPILER ERRORs (ICEs) are, in fact, caused
  93. by an ETI-related problem somewhere deep down the instantiation stack.</p>
  94. </div>
  95. <div class="section" id="eti-the-solution">
  96. <h2><a name="eti-the-solution">The Solution</a></h2>
  97. <p>There is no way we can change the compiler's behavior in this case, so what we have
  98. to do is to adjust to it and still make our templates do what we want. Surprisingly,
  99. in most cases it's quite simple to achieve:</p>
  100. <pre class="literal-block">
  101. // potentially unsafe
  102. template&lt; typename F &gt; struct apply0
  103. {
  104. typedef typename F::type type;
  105. };
  106. // now ETI-safe
  107. template&lt;&gt; struct apply0&lt;int&gt;
  108. {
  109. typedef int type;
  110. };
  111. </pre>
  112. <p>Since the original template could have never been instantiated with <tt class="literal"><span class="pre">int</span></tt>,
  113. providing a stub <tt class="literal"><span class="pre">int</span></tt> specialization is completely innocent.</p>
  114. <!-- Looks like you're missing lots of stuff, like ETI_BASE - - no? -->
  115. </div>
  116. </div>
  117. <div class="footer-separator"></div>
  118. <table class="footer"><tr class="footer"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./incomplete-support-for.html" class="navigation-link">Prev</a>&nbsp;<a href="./resources.html" class="navigation-link">Next</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group"><a href="./incomplete-support-for.html" class="navigation-link">Back</a>&nbsp;Along</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>
  119. </tr></table></body>
  120. </html>