microsoft_vcpp.html 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  4. <title>Portability Hints: Microsoft Visual C++ 6.0 SP4</title>
  5. </head>
  6. <body bgcolor="#FFFFFF" text="#000000">
  7. <table border="1" bgcolor="#007F7F" cellpadding="2">
  8. <tr>
  9. <td bgcolor="#FFFFFF"><img src="../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86"></td>
  10. <td><a href="../index.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>Home</big></font></a></td>
  11. <td><a href="../libs/libraries.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>Libraries</big></font></a></td>
  12. <td><a href="../people/people.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>People</big></font></a></td>
  13. <td><a href="faq.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>FAQ</big></font></a></td>
  14. <td><a href="index.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>More</big></font></a></td>
  15. </tr>
  16. </table>
  17. <p>
  18. <h1>Portability Hints: Microsoft Visual C++ 6.0 SP4</h1>
  19. Similar to the
  20. <a href="borland_cpp.html">portability hints for Borland C++</a>,
  21. this page provides hints on some language features of the Microsoft Visual C++
  22. version 6.0 service pack 4 compiler. A list of
  23. acknowledged deficiencies can be found at the
  24. <a href="http://support.microsoft.com/support/kb/articles/q243/4/51.asp">Microsoft support site</a>.
  25. <p>
  26. Each entry in the following list describes a particular issue,
  27. complete with sample source code to demonstrate the effect.
  28. Most sample code herein has been verified to compile with gcc 2.95.2
  29. and Comeau C++ 4.2.44.
  30. <h2>Preprocessor symbol</h2>
  31. The preprocessor symbol <code>_MSC_VER</code> is defined for all
  32. Microsoft C++ compilers. Its value is the internal version number of the
  33. compiler interpreted as a decimal number. Since a few other compilers
  34. also define this symbol, boost provides the symbol
  35. <code>BOOST_MSVC</code>, which is defined in
  36. <a href="../boost/config.hpp">boost/config.hpp</a>
  37. to the value of _MSC_VER if and only if the compiler is really
  38. Microsoft Visual C++.
  39. The following table lists some known values.
  40. <p>
  41. <table border="1">
  42. <tr>
  43. <th>Compiler</th>
  44. <th><code>BOOST_MSVC</code> value</th>
  45. </tr>
  46. <tr>
  47. <td>Microsoft Visual C++ 6.0 (up to SP4)</td>
  48. <td>1200</td>
  49. </tr>
  50. </table>
  51. <h2>Core Language</h2>
  52. <h3>[chained using] Chaining <code>using</code>-declarations</h3>
  53. Chaining <code>using</code>-declarations does not work.
  54. <pre>
  55. void f();
  56. namespace N {
  57. using ::f;
  58. }
  59. void g()
  60. {
  61. using N::f; // C2873: 'f': the symbol cannot be used in a using-declaration
  62. }
  63. </pre>
  64. <h3>[explicit-instantiation] Explicit function template
  65. instantiation</h3>
  66. Trying to explicitly instantiate a function template leads to the
  67. wrong function being called silently.
  68. <pre>
  69. #include &lt;stdio.h&gt;
  70. template&lt;class T&gt;
  71. void f()
  72. {
  73. printf(&quot;%d\n&quot;, sizeof(T));
  74. }
  75. int main()
  76. {
  77. f&lt;double&gt;(); // output: &quot;1&quot;
  78. f&lt;char&gt;(); // output: &quot;1&quot;
  79. return 0;
  80. }
  81. </pre>
  82. <h3>[for-scoping] Scopes of definitions in for-loops</h3>
  83. The scope of variable definitions in <code>for</code> loops should be
  84. local to the loop's body, but it is instead local to the enclosing
  85. block.
  86. <pre>
  87. int main()
  88. {
  89. for(int i = 0; i &lt; 5; ++i)
  90. ;
  91. for(int i = 0; i &lt; 5; ++i) // C2374: 'i': Redefinition; multiple initialization
  92. ;
  93. return 0;
  94. }
  95. </pre>
  96. <strong>Workaround:</strong> Enclose the offending <code>for</code>
  97. loops in another pair of curly braces.
  98. <p>
  99. Another possible workaround (brought to my attention by Vesa Karvonen)
  100. is this:
  101. <pre>
  102. #ifndef for
  103. #define for if (0) {} else for
  104. #endif
  105. </pre>
  106. Note that platform-specific inline functions in included headers might
  107. depend on the old-style <code>for</code> scoping.
  108. <h3>[inclass-member-init] In-class member initialization</h3>
  109. In-class member initialization, required to implement a
  110. Standard-conforming <code>std::numeric_limits</code> template, does
  111. not work.
  112. <pre>
  113. struct A
  114. {
  115. static const int i = 5; // &quot;invalid syntax for pure virtual method&quot;
  116. };
  117. </pre>
  118. <strong>Workaround:</strong> Either use an enum (which has incorrect
  119. type, but can be used in compile-time constant expressions), or define
  120. the value out-of-line (which allows for the correct type, but prohibits
  121. using the constant in compile-time constant expressions). See
  122. <a href="int_const_guidelines.htm">Coding Guidelines for Integral Constant Expressions</a>
  123. for guidelines how to define member constants portably in boost
  124. libraries.
  125. <h3>[koenig-lookup] Argument-dependent lookup</h3>
  126. Argument-dependent lookup, also called Koenig lookup, works for
  127. overloaded operators, but not for ordinary functions. No
  128. additional namespaces induced from the argument types seem to be
  129. considered.
  130. <pre>
  131. namespace N {
  132. struct A {};
  133. void f(A);
  134. }
  135. void g()
  136. {
  137. N::A a;
  138. f(a); // 'f': undeclared identifier
  139. }
  140. </pre>
  141. <h3>[template-friend] Templates as friends</h3>
  142. A Template cannot be declared a friend of a class.
  143. <pre>
  144. template&lt;class T&gt;
  145. struct A {};
  146. struct B
  147. {
  148. template&lt;class T&gt;
  149. friend struct A; // &quot;syntax error&quot;
  150. };
  151. </pre>
  152. <h3>[member-template-outofline] Out-of-line definitions of member
  153. templates</h3>
  154. Defining member templates outside their enclosing class does not work.
  155. <pre>
  156. template&lt;class T&gt;
  157. struct A
  158. {
  159. template&lt;class U&gt;
  160. void f();
  161. };
  162. template&lt;class T&gt;
  163. template&lt;class U&gt; // &quot;syntax error&quot;
  164. void A&lt;T&gt;::f() // &quot;T: undeclared identifier&quot;
  165. {
  166. }
  167. </pre>
  168. <strong>Workaround:</strong> Define member templates in-line within
  169. their enclosing class.
  170. <h3>[partial-spec] Partial specialization</h3>
  171. Partial specialization of class templates does not work.
  172. <pre>
  173. template&lt;class T&gt;
  174. struct A {};
  175. template&lt;class T&gt;
  176. struct B {};
  177. template&lt;class T&gt;
  178. struct A&lt;B&lt;T&gt; &gt; {}; // template class was already defined as a non-template
  179. </pre>
  180. <strong>Workaround:</strong> In some situations where interface
  181. does not matter, class member templates can simulate partial
  182. specialization.
  183. <h3>[template-value] Dependent template value parameters</h3>
  184. Template value parameters whose type depends on a previous template
  185. parameter provoke an internal compiler error if the correct syntax
  186. (with "typename") is used.
  187. <pre>
  188. template&lt;class T, typename T::result_type&gt; // C1001: INTERNAL COMPILER ERROR: msc1.cpp, line 1794
  189. struct B {};
  190. // (omit &quot;typename&quot; and it compiles)
  191. </pre>
  192. <strong>Workaround:</strong> Leave off the "typename" keyword. That makes
  193. the program non-conforming, though.
  194. <h3>[wchar_t] <code>wchar_t</code> is not built-in</h3>
  195. The type <code>wchar_t</code> is not a built-in type.
  196. <pre>
  197. wchar_t x; // &quot;missing storage class or type identifier&quot;
  198. </pre>
  199. <strong>Workaround:</strong> When using Microsoft Visual C++, the
  200. header
  201. <a href="../boost/config.hpp">boost/config.hpp</a>
  202. includes <code>&lt;cstddef></code>, which defines
  203. <code>wchar_t</code> as a typedef for <code>unsigned
  204. short</code>. Note that this means that the compiler does not regard
  205. <code>wchar_t</code> and <code>unsigned short</code> as distinct
  206. types, as is required by the standard, and so ambiguities may emanate
  207. when overloading on <code>wchar_t</code>. The macro
  208. <code>BOOST_NO_INTRINSIC_WCHAR_T</code> is defined in this situation.
  209. <h3>[delete-const-pointer] Deleting <code>const X *</code> does not work</h3>
  210. Trying to delete a pointer to a cv-qualified type gives an error:
  211. <pre>
  212. void f()
  213. {
  214. const int *p = new int(5);
  215. delete p; // C2664: cannot convert from "const int *" to "void *"
  216. }
  217. </pre>
  218. <strong>Workaround:</strong> Define the function
  219. <pre>
  220. inline void operator delete(const void *p) throw()
  221. { operator delete(const_cast&lt;void*>(p)); }
  222. </pre>
  223. and similar functions for the other cv-qualifier combinations, for
  224. operator delete[], and for the <code>std::nothrow</code> variants.
  225. <h2>Standard Library</h2>
  226. <h3>[clib-namespace] C library names in global namespace instead of std</h3>
  227. <p>Library names from the &lt;c...&gt; headers are in the global namespace
  228. instead of namespace std.<p><b>Workaround:</b>&nbsp; The header <a href="../libs/config/config.htm">boost/config.hpp</a>
  229. will define BOOST_NO_STDC_NAMESPACE. It can be used as follows:
  230. <pre># ifdef BOOST_NO_STDC_NAMESPACE
  231. namespace std { using ::abs; using ::fabs; }
  232. # endif</pre>
  233. <p>Because std::size_t and std::ptrdiff_t are so commonly used, the workaround
  234. for these is already provided in boost/config.hpp.<p>&nbsp;
  235. <hr>
  236. 2001-05-04 <a href="../people/jens_maurer.htm">Jens Maurer</a>
  237. </body>
  238. </html>
粤ICP备19079148号