Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/more/borland_cpp.html @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 10.3 KB
Line 
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2<html>
3<head>
4<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
5<title>Portability Hints: Borland C++ 5.5.1</title>
6</head>
7
8<body bgcolor="#FFFFFF" text="#000000">
9
10<table border="1" bgcolor="#007F7F" cellpadding="2">
11  <tr>
12    <td bgcolor="#FFFFFF"><img src="../boost.png" alt="boost.png (6897 bytes)" width="277" height="86"></td>
13    <td><a href="../index.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>Home</big></font></a></td>
14    <td><a href="../libs/libraries.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>Libraries</big></font></a></td>
15    <td><a href="../people/people.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>People</big></font></a></td>
16    <td><a href="faq.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>FAQ</big></font></a></td>
17    <td><a href="index.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>More</big></font></a></td>
18  </tr>
19</table>
20
21<p>
22
23<h1>Portability Hints: Borland C++ 5.5.1</h1>
24
25It is a general aim for boost libraries to be
26<a href="lib_guide.htm#Portability">portable</a>.  The primary means
27for achieving this goal is to adhere to ISO Standard C++.  However,
28ISO C++ is a broad and complex standard and most compilers are
29not fully conformant to ISO C++ yet.  In order to achieve portability
30in the light of this restriction, it seems advisable to get acquainted
31with those language features that some compilers do not fully
32implement yet.
33<p>
34
35This page gives portability hints on some language features of the
36Borland C++ version 5.5.1 compiler.  Furthermore, the appendix
37presents additional problems with Borland C++ version 5.5.  Borland
38C++ 5.5.1 is a freely available command-line compiler for Win32
39available at
40<a href="http://www.borland.com/">http://www.borland.com/</a>.
41<p>
42
43Each entry in the following list describes a particular issue,
44complete with sample source code to demonstrate the effect.
45Most sample code herein has been verified to compile with gcc 2.95.2
46and Comeau C++ 4.2.44.
47
48
49<h2>Preprocessor symbol</h2>
50
51The preprocessor symbol <code>__BORLANDC__</code> is defined for all
52Borland C++ compilers.  Its value is the version number of the
53compiler interpreted as a hexadecimal number.  The following table
54lists some known values.
55<p>
56
57<table border="1">
58<tr>
59<th>Compiler</th>
60<th><code>__BORLANDC__</code> value</th>
61</tr>
62
63<tr>
64<td>Borland C++ Builder 4</td>
65<td>0x0540</td>
66</tr>
67
68<tr>
69<td>Borland C++ Builder 5</td>
70<td>0x0550</td>
71</tr>
72
73<tr>
74<td>Borland C++ 5.5</td>
75<td>0x0550</td>
76</tr>
77
78<tr>
79<td>Borland C++ 5.5.1</td>
80<td>0x0551</td>
81</tr>
82
83<tr>
84<td>Borland C++ Builder 6</td>
85<td>0x0560</td>
86</tr>
87
88</table>
89
90<h2>Core Language</h2>
91
92<h3>[using-directive] Mixing <code>using</code>-declarations and
93<code>using</code>-directives</h3>
94
95Mixing <code>using</code>-directives (which refer to whole namespaces)
96and namespace-level <code>using</code>-declarations (which refer to
97individual identifiers within foreign namespaces) causes ambiguities
98where there are none.  The following code fragment illustrates this:
99
100<pre>
101namespace N {
102  int x();
103}
104
105using N::x;
106using namespace N;
107
108int main()
109{
110  &amp;x;     // Ambiguous overload
111}
112</pre>
113
114
115<h3>[using template] <code>using</code>-declarations for class
116templates</h3>
117
118Identifiers for class templates can be used as arguments to
119<code>using</code>-declarations as any other identifier.  However, the
120following code fails to compile with Borland C++:
121
122<pre>
123template&lt;class T&gt;
124class X { };
125
126namespace N
127{
128  // "cannot use template 'X&lt;T&gt;' without specifying specialization parameters"
129  using ::X;
130};
131</pre>
132
133
134<h3>[template const arg] Deduction of constant arguments to function
135templates</h3>
136
137Template function type deduction should omit top-level constness.
138However, this code fragment instantiates "f&lt;const int&gt;(int)":
139
140<pre>
141template&lt;class T&gt;
142void f(T x)
143{
144        x = 1;  // works
145        (void) &amp;x;
146        T y = 17;
147        y = 20;  // "Cannot modify a const object in function f&lt;const int&gt;(int)"
148        (void) &amp;y;
149}
150
151int main()
152{
153        const int i = 17;
154        f(i);
155}
156</pre>
157
158The boost/rational.hpp header exhibits this problem in connection with
159the gcd() function.
160
161
162<h3>[function address] Resolving addresses of overloaded
163functions</h3>
164
165Addresses of overloaded functions are not in all contexts properly
166resolved (std:13.4 [over.over]); here is a small example:
167<pre>
168template&lt;class Arg&gt;
169void f( void(*g)(Arg) );
170
171void h(int);
172void h(double);
173
174template&lt;class T&gt;
175void h2(T);
176
177int main()
178{
179  void (*p)(int) = h;            // this works (std:13.4-1.1)
180  void (*p2)(unsigned char) = h2;    // this works as well (std:13.4-1.1)
181  f&lt;int&gt;(h2);  // this also works (std:13.4-1.3)
182
183  // "Cannot generate template specialization from h(int)",
184  // "Could not find a match for f&lt;Arg&gt;(void (*)(int))"
185  f&lt;double&gt;(h);   // should work (std:13.4-1.3)
186
187  f( (void(*)(double))h);  // C-style cast works (std:13.4-1.6 with 5.4)
188
189  // "Overloaded 'h' ambiguous in this context"
190  f(static_cast&lt;void(*)(double)&gt;(h)); // should work (std:13.4-1.6 with 5.2.9)
191}
192</pre>
193
194<strong>Workaround:</strong> Always use C-style casts when determining
195addresses of (potentially) overloaded functions.
196
197<h3>[string conversion] Converting <code>const char *</code> to
198<code>std::string</code></h3>
199
200Implicitly converting <code>const char *</code> parameters to
201<code>std::string</code> arguments fails if template functions are
202explicitly instantiated (it works in the usual cases, though):
203
204<pre>
205#include &lt;string&gt;
206
207template&lt;class T&gt;
208void f(const std::string &amp; s)
209{}
210
211int main()
212{
213  f&lt;double&gt;("hello");  // "Could not find a match for f&lt;T&gt;(char *)"
214}
215
216</pre>
217
218<strong>Workaround:</strong> Avoid explicit template function
219instantiations (they have significant problems with Microsoft Visual
220C++) and pass default-constructed unused dummy arguments with the
221appropriate type.  Alternatively, if you wish to keep to the explicit
222instantiation, you could use an explicit conversion to
223<code>std::string</code> or declare the template function as taking a
224<code>const char *</code> parameter.
225
226
227<h3>[template value defaults] Dependent default arguments for template
228value parameters</h3>
229
230Template value parameters which default to an expression dependent on
231previous template parameters don't work:
232
233<pre>
234template&lt;class T&gt;
235struct A
236{
237  static const bool value = true;
238};
239
240// "Templates must be classes or functions", "Declaration syntax error"
241template&lt;class T, bool v = A&lt;T&gt;::value&gt;
242struct B {};
243
244int main()
245{
246  B&lt;int&gt; x;
247}
248
249</pre>
250
251
252<strong>Workaround:</strong> If the relevant non-type template
253parameter is an implementation detail, use inheritance and a fully
254qualified identifier (for example, ::N::A&lt;T&gt;::value).
255
256
257<h3>[function partial ordering] Partial ordering of function
258templates</h3>
259
260Partial ordering of function templates, as described in std:14.5.5.2
261[temp.func.order], does not work:
262
263<pre>
264#include &lt;iostream&gt;
265
266template&lt;class T&gt; struct A {};
267
268template&lt;class T1&gt;
269void f(const A&lt;T1&gt; &)
270{
271  std::cout << "f(const A&lt;T1&gt;&)\n";
272}
273
274template&lt;class T&gt;
275void f(T)
276{
277  std::cout << "f(T)\n";
278}
279
280int main()
281{
282  A&lt;double&gt; a;
283  f(a);   // output: f(T)  (wrong)
284  f(1);   // output: f(T)  (correct)
285}
286</pre>
287
288<strong>Workaround:</strong> Declare all such functions uniformly as
289either taking a value or a reference parameter.
290
291
292<h3>[instantiate memfun ptr] Instantiation with member function pointer</h3>
293
294When directly instantiating a template with some member function
295pointer, which is itself dependent on some template parameter, the
296compiler cannot cope:
297<pre>
298template&lt;class U&gt; class C { };
299template&lt;class T&gt;
300class A
301{
302  static const int v = C&lt;void (T::*)()&gt;::value;
303};
304</pre>
305
306<strong>Workaround:</strong> Use an intermediate <code>typedef</code>:
307
308<pre>
309template&lt;class U&gt; class C { };
310template&lt;class T&gt;
311class A
312{
313  typedef void (T::*my_type)();
314  static const int v = C&lt;my_type&gt;::value;
315};
316</pre>
317
318(Extracted from e-mail exchange of David Abrahams, Fernando Cacciola,
319and Peter Dimov; not actually tested.)
320
321
322<h2>Library</h2>
323
324
325<h3>[cmath.abs] Function <code>double std::abs(double)</code>
326missing</h3>
327
328The function <code>double std::abs(double)</code> should be defined
329(std:26.5-5 [lib.c.math]), but it is not:
330
331<pre>
332#include &lt;cmath&gt;
333
334int main()
335{
336  double (*p)(double) = std::abs;  // error
337}
338</pre>
339
340Note that <code>int std::abs(int)</code> will be used without warning
341if you write <code>std::abs(5.1)</code>.
342<p>
343Similar remarks apply to seemingly all of the other standard math
344functions, where Borland C++ fails to provide <code>float</code> and
345<code>long double</code> overloads.
346<p>
347<strong>Workaround:</strong> Use <code>std::fabs</code> instead if
348type genericity is not required.
349
350<h2>Appendix: Additional issues with Borland C++ version 5.5</h2>
351
352These issues are documented mainly for historic reasons.  If you are
353still using Borland C++ version 5.5, you are strongly encouraged to
354obtain an upgrade to version 5.5.1, which fixes the issues described
355in this section.
356
357<h3>[inline friend] Inline friend functions in template classes</h3>
358
359If a friend function of some class has not been declared before the
360friend function declaration, the function is declared at the namespace
361scope surrounding the class definition.  Together with class templates
362and inline definitions of friend functions, the code in the following
363fragment should declare (and define) a non-template function "bool
364N::f(int,int)", which is a friend of class N::A&lt;int&gt;.  However,
365Borland C++ v5.5 expects the function f to be declared beforehand:
366
367<pre>
368namespace N {
369template&lt;class T&gt;
370class A
371{
372  // "f is not a member of 'N' in function main()"
373  friend bool f(T x, T y) { return x < y; }
374};
375}
376
377int main()
378{
379  N::A&lt;int&gt; a;
380}
381</pre>
382
383This technique is extensively used in boost/operators.hpp.  Giving in
384to the wish of the compiler doesn't work in this case, because then
385the "instantiate one template, get lots of helper functions at
386namespace scope" approach doesn't work anymore.  Defining
387BOOST_NO_OPERATORS_IN_NAMESPACE (a define
388BOOST_NO_INLINE_FRIENDS_IN_CLASS_TEMPLATES would match this case
389better) works around this problem and leads to another one, see
390[using-template].
391
392<p>
393
394<hr>
395
3962000-09-30 <a href="../people/jens_maurer.htm">Jens Maurer</a>
397</body>
398</html>
Note: See TracBrowser for help on using the repository browser.