source: git/ntl/doc/tour-stdcxx.html @ 199b5c

fieker-DuValspielwiese
Last change on this file since 199b5c was 2cfffe, checked in by Hans Schönemann <hannes@…>, 22 years ago
This commit was generated by cvs2svn to compensate for changes in r6316, which included commits to RCS files with non-trunk default branches. git-svn-id: file:///usr/local/Singular/svn/trunk@6317 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 19.5 KB
Line 
1<html>
2<head>
3<title>
4A Tour of NTL: Traditional and ISO Modes  </title>
5</head>
6
7<body bgcolor="#fff9e6">
8<center>
9<a href="tour-modules.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a>
10 <a href="tour.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> 
11<a href="tour-unix.html"> <img src="arrow3.gif" alt="[Next]" align=bottom></a>
12</center>
13
14<h1> 
15<p align=center>
16A Tour of NTL: Traditional and ISO Modes
17</p>
18</h1>
19
20<p> <hr> <p>
21
22<p>
23
24As of version 4.1,
25NTL can be compiled and used in one of two modes: Traditional or ISO.
26To get ISO mode, you can pass <tt>NTL_STD_CXX=on</tt>
27as an argument to the configuration script
28when <a href="tour-unix.html">installing NTL on a Unix or Unix-like system</a>.
29This will set the flag <tt>NTL_STD_CXX</tt> in the <tt>config.h</tt>
30file.
31Alternatively (and especially on non-Unix systems),
32you can set this flag  by hand by editing
33the the <tt>config.h</tt> file.
34<p>
35
36Traditional mode provides the same interface as that provided
37in versions 4.0 and earlier.
38Traditional mode is also the default, so old programs that used NTL
39should continue to work without any changes.
40So if you wish, you can completely ignore the new ISO mode, and ignore
41the rest of this page.
42However, if you want to fully exploit some important,
43new features of <tt>C++</tt>, in particular <i>namespaces</i>, read on.
44Also, it is likely that in future distributions of NTL, ISO mode will become
45the default mode, although Traditional mode will continue to
46be supported indefinitely.
47
48<p>
49In Traditional mode, the NTL header files include the traditional
50<tt>C++</tt> header files <tt>&lt;stdlib.h&gt;</tt>,
51<tt>&lt;math.h&gt;</tt>, and <tt>&lt;iostream.h&gt;</tt>.
52These files declare a number of names (functions, types, etc.)
53in the <i>global namespace</i>.
54Additionally, the NTL header files declare a number of names,
55also in the global namespace.
56
57<p>
58In ISO mode, three things change:
59
60<ol>
61<li>
62<b>NTL namespace:</b>
63The NTL header files wrap all NTL names in a namespace, called <tt>NTL</tt>.
64
65<p>
66<li>
67<b>New header files:</b>
68The NTL header files include the new <tt>C++</tt> 
69header files <tt>&lt;cstdlib&gt;</tt>,
70<tt>&lt;cmath&gt;</tt>, and <tt>&lt;iostream&gt;</tt>.
71These new header files are essentially the same as the traditional ones,
72except that all the the names are declared in a namespace called
73<tt>std</tt>.
74
75<p>
76<li>
77<b>Nothrow new:</b>
78The NTL implementation files use the <tt>nothrow</tt> version of <tt>new</tt>.
79</ol>
80
81
82<p>
83ISO mode uses <tt>C++</tt> features that are new to
84the new ISO <tt>C++</tt> standard.
85I know of no compiler that truly implements all of the standard,
86but some come pretty close.
87If your complier is too old, you will not be able to use NTL in ISO
88mode;  otherwise, you are free to use either ISO or Traditional mode,
89but I would recommend ISO mode for code that you expect to
90be around for a long time.
91In particular, if you want to develop and distribute a library that
92builds on top of NTL, it would be preferable to make it compatible
93with NTL in ISO mode, and even better, to make it compatible with
94either mode.
95
96<p>
97If your complier is not up to date, but you want some of the benefits
98of Standard <tt>C++</tt>, you can set the <i>partial standard</i>
99flags to get any subset of the above three changes:
100<p>
101<ol>
102<li>
103<tt>NTL_PSTD_NNS</tt>: NTL namespace
104<li>
105<tt>NTL_PSTD_NHF</tt>: New header files
106<li>
107<tt>NTL_PSTD_NTN</tt>: Nothrow new
108</ol>
109
110You can set these flags either by using the configuration script
111(only on Unix-like systems), or by editing the <tt>config.h</tt> file.
112For example, to just wrap NTL in a namepsace, just pass
113<tt>NTL_PSTD_NNS=on</tt>
114as an argument to the configuration script
115when installing NTL.
116
117<p>
118
119Especially when combining NTL with other libraries, the
120<tt>NTL_PSTD_NNS</tt> flag may be particularly useful
121in avoiding name clashes, even if your compiler has just a
122rudimentary implementation of namespaces.
123
124<p>
125NTL will remain usable in Traditional indefinitely,
126assuming compilers maintain reasonable backward compatibilty with
127pre-standard <tt>C++</tt> conventions for header files;
128however, if you want to <i>program for the future</i>, it is recommended
129to use ISO mode.
130The partial ISO modes are not highly recommended;
131they are mainly intended as a stop-gap measure
132while we wait for decent standard-conforming <tt>C++</tt>
133compilers to become available.
134
135
136<p>
137<h3>
138A crash course on namespaces
139</h3>
140
141<p>
142As already mentioned, the main difference between Traditional and ISO
143mode is that in ISO mode, all names are wrapped in namespaces.
144Namespaces are a feature that was introduced in the new <tt>C++</tt> standard.
145One can declare names (functions, types, etc.) inside a namespace.
146By default,
147such names are not visible outside the namespace without explicit
148qualification.
149
150<p>
151The main advantage of namespaces is that it solves the <i>namespace pollution
152problem</i>:
153if two libraries define the same name in two inconsistent ways,
154it is very difficult, if not impossible,
155to combine these two libraries in the same
156program.
157
158<p>
159The traditional way of avoiding such problems in languages like
160<tt>C</tt> is for a library designer to attach a prefix specific
161to that library to all names.
162This works, but makes for ugly code.
163The function overloading mechanism in <tt>C++</tt> eases the problem a bit,
164but is still not a complete solution.
165
166<p>
167
168The new
169namespace feature in <tt>C++</tt>
170provides a reasonably complete and elegant solution to the namespace
171pollution problem.
172It is one of the nicest and most important recent additions to the <tt>C++</tt>
173language.
174
175<p>
176
177Here is a simple example to illustrate namespaces.
178<p>
179<pre>
180
181namespace N {
182   void f(int);
183   void g(int);
184   int x;
185}
186
187int x;
188
189void h()
190{
191   x = 1;    // the global x
192   N::x = 0; // the x in namespace N
193   N::f(0);  // the f in namespace N
194   g(1);     // error -- g is not visible here
195}
196
197</pre>
198
199<p>
200All of this explicit qualification business
201can be a bit tedious.
202The easiest way to avoid this tedium is to use what is called
203a <i>using directive</i>, which effectively makes
204all names declared within a namespace visible in the
205global scope.
206
207Here is a variation on the previous example, with a using directive.
208
209<p>
210<pre>
211
212namespace N {
213   void f(int);
214   void g(int);
215   int x;
216}
217
218int x;
219
220using namespace N;
221
222void h()
223{
224   x = 1;    // error -- ambiguous: the global x or the x in namespace N?
225   ::x = 1;  // the global x
226   N::x = 0; // the x in namespace N
227   N::f(0);  // the f in namespace N
228   f(0);     // OK -- N::f(int) is visible here
229   g(1);     // OK -- N::g(int) is visible here
230}
231
232</pre>
233
234<p>
235Here is another example.
236
237<p>
238<pre>
239
240namespace N1 {
241   int x;
242   void f(int);
243   void g(int);
244}
245
246namespace N2 {
247   int x;
248   int y;
249   void f(double);
250   void g(int);
251}
252
253using namespace N1;
254using namespace N2;
255
256void h()
257{
258   x = 1;     // error -- ambiguous: N1::x or N2::x?
259   N1::x = 1; // OK
260   N2::x = 1; // OK
261   y = 1;     // OK  -- this is N2::y
262   g(0);      // error -- ambiguous: N1::g(int) or N2::g(int)?
263   f(0);      // OK -- N1::f(int), because it is the "best" match
264   f(0.0);    // OK  -- N2::f(double), because it is the "best" match
265}
266
267</pre>
268
269<p>
270This example illustrates the interaction between using declarations
271and function overloading resolution.
272If several overloaded versions of a function are visible,
273it is not necessarily ambiguous: the usual overload resolution
274procedure is applied, and if there is a unique "best" match,
275then there is no ambiguity.
276
277<p>
278
279The examples presented here do not illustrate all of the
280features and nuances of namespaces.
281For this, you are referred to a <tt>C++</tt> book.
282
283<p>
284<h3>
285Namespaces and NTL
286</h3>
287
288<p>
289In ISO mode, the standard library is "wrapped" in namespace <tt>std</tt>,
290and NTL is "wrapped" in namespace <tt>NTL</tt>.
291Thus, the header file <tt>&lt;NTL/ZZ.h&gt;</tt> in ISO mode looks
292something like this:
293<pre>
294
295namespace NTL {
296
297   // ...
298
299   class ZZ { /* ... */ };
300
301   // ...
302
303   ZZ operator+(const ZZ&amp; a, const ZZ&amp; b);
304   ZZ operator*(const ZZ&amp; a, const ZZ&amp; b);
305
306   std::istream&amp; operator>>(std::istream&amp; s, ZZ&amp; x);
307   std::ostream&amp; operator<<(std::ostream&amp; s, const ZZ&amp; a);
308
309   // ...
310
311 
312}
313
314</pre>
315
316Therefore, one must explicitly qualify all names, or use appropriate
317using directives.
318Here is how one could write the <a href="tour-ex1.html">first example</a> 
319of the tour in
320ISO mode.
321
322<pre>
323
324#include &lt;NTL/ZZ.h&gt;
325
326int main()
327{
328   NTL::ZZ a, b, c;
329
330   std::cin &gt;&gt; a;
331   std::cin &gt;&gt; b;
332   c = (a+1)*(b+1);
333   std::cout &lt;&lt; c &lt;&lt; "\n";
334}
335
336</pre>
337
338<p>
339Notice how everything is explicitly qualified.
340Actually, the input/output operators <tt>&lt;&lt;</tt> and <tt>&gt;&gt;</tt>,
341and the arithmetic operators <tt>+</tt> and <tt>*</tt> are not explicitly
342qualified, but rather, the compiler finds them through a gimmick
343called <i>Koenig Lookup</i>, which will look for functions (and operators)
344declared in namespace <tt>NTL</tt>, because the type of the argument
345(<tt>ZZ</tt>) is a class declared in that namespace.
346
347<p>
348
349Even with Koenig Lookup, explicit qualification can
350be a bit tedious.
351Here is the same example, this time with using directives.
352
353<pre>
354
355#include &lt;NTL/ZZ.h&gt;
356
357using namespace NTL;
358using namespace std;
359
360int main()
361{
362   ZZ a, b, c;
363
364   cin &gt;&gt; a;
365   cin &gt;&gt; b;
366   c = (a+1)*(b+1);
367   cout &lt;&lt; c &lt;&lt; "\n";
368}
369
370</pre>
371
372To write NTL client code that will compile smoothly in either
373Traditional or ISO mode, one simply does the following:
374
375<pre>
376
377#include &lt;NTL/ZZ.h&gt;
378
379NTL_CLIENT
380
381int main()
382{
383   ZZ a, b, c;
384
385   cin &gt;&gt; a;
386   cin &gt;&gt; b;
387   c = (a+1)*(b+1);
388   cout &lt;&lt; c &lt;&lt; "\n";
389}
390
391</pre>
392
393<p>
394Here, <tt>NTL_CLIENT</tt> is a macro defined by NTL
395that expands into zero, one, or two appropriate <i>using</i> directives,
396depending on the settings of <tt>NTL_STD_CXX</tt>,
397<tt>NTL_PSTD_NNS</tt>, and <tt>NTL_PSTD_NHF</tt>.
398Alternatively, instead of using the <tt>NTL_CLIENT</tt> macro,
399you can write:
400<p>
401
402<pre>
403#if (defined(NTL_PSTD_NNS) || defined(NTL_STD_CXX))
404   using namespace NTL;
405#endif
406
407#if (defined(NTL_PSTD_NHF) || defined(NTL_STD_CXX))
408   using namespace std;
409#endif
410</pre>
411
412Typically,
413when writing a program that uses NTL,
414you can
415simply insert the <tt>NTL_CLIENT</tt> as above,
416and forget about all this namespace nonsense.
417However, if you are combining libraries, you may have to disambiguate
418things from time to time.
419
420<p>
421
422The Standard <tt>C++</tt> library is huge.
423If you just use <tt>&lt;iostream&gt;</tt>, you should not
424have any ambiguous names.
425However, there are some potential ambiguities in the STL
426(Standard Template Library) part of the library.
427One that I know of is the template class <tt>negate</tt>
428defined in <tt>&lt;functional&gt;</tt>, which conflicts with the
429NTL function <tt>negate</tt>.
430With namespaces, there should be no problem, unless the client
431code explicitly uses <tt>negate</tt>, in which case you will
432have to explicitly qualify <tt>negate</tt> to tell the compiler
433which <tt>negate</tt> you mean, either <tt>std::negate</tt>
434or <tt>NTL::negate</tt>.
435
436<p>
437NTL also explicitly defines various versions of <tt>min</tt>
438and <tt>max</tt> functions.
439Template versions of these functions are also defined in the
440standard library component <tt>&lt;algorithm&gt;</tt>.
441Because of the way the function overload resolution mechanism works,
442the "right" version of <tt>min</tt> or <tt>max</tt> should always
443be chosen, without any need for explicit qualification.
444
445<p>
446There may be other possible ambiguities between the standard library
447and NTL, but if they arise, they are easily fixed through
448explicit qualification.
449
450<p>
451<h3>
452Some global names
453</h3>
454<p>
455
456It is not quite true that <i>all</i> names
457declared in NTL header files are wrapped in namespace NTL.
458There are two classes of exceptions:
459<p>
460<ul>
461<li>
462All names that start with the prefix "<tt>NTL_</tt>"
463are in fact <i>macros</i>
464There are a number of documented and undocumented
465such macros.
466Note that any name with this prefix is a macro and all macros
467start with this prefix.
468
469<p>
470
471<li>
472There are also a number of undocumented names that start with the
473prefix "<tt>_ntl_</tt>".
474These are not macros, but rather are names of functions, types, etc.,
475that are declared in the global namespace.
476Any name with this prefix is in the global namespace,
477and all names in the global namespace start with this prefix.
478All functions with <tt>"C"</tt> linkage have this prefix.
479</ul>
480<p>
481Thus, NTL "owns" all names starting with "<tt>NTL_</tt>" or "<tt>_ntl_</tt>";
482users of NTL should avoid names with these prefixes.
483
484<p>
485<h3>
486Further technicalities
487</h3>
488<p>
489
490Another thing to be aware of is that there are some small, annoying
491differences between the old standard <tt>C</tt> include files
492<tt>&lt;stdlib.h&gt;</tt> and <tt>&lt;math.h&gt;</tt>,
493and the new <tt>C++</tt> include files
494<tt>&lt;cstdlib&gt;</tt> and <tt>&lt;cmath&gt;</tt>,
495above and beyond the namespace wrapping.
496Specifically, the new header files declare several overloaded versions
497of some functions.
498For example, in the old header files, there was one function
499<pre>
500   int abs(int);
501</pre>
502Now there are several, including:
503<pre>
504   int abs(int);
505   long abs(long);
506   float abs(float);
507   double abs(double);
508   long double abs(long double);
509</pre>
510Also, functions like <tt>log</tt> and <tt>sqrt</tt> are also overloaded.
511So instead of just
512<pre>
513   double log(double);
514</pre>
515there are
516<pre>
517   float log(float);
518   double log(double);
519   long double log(long double);
520</pre>
521
522<p>
523This can lead to compile-time errors in some old codes, such as:
524<pre>
525   double log_2 = log(2);
526</pre>
527
528<p>
529With the old header files, the <tt>int</tt> value 2 would have
530been converted to a <tt>double</tt>, and the function
531<pre>
532   double log(double);
533</pre>
534would have been called.
535<p>
536With the new header files, the compiler would raise an error,
537because the function call is now ambiguous.
538<p>
539Of course, the fix is trivial:
540<pre>
541   double log_2 = log(2.0);
542</pre>
543This will compile correctly with either old or new header files.
544
545<p>
546Don't you just love the ISO?
547
548
549<p>
550<h3>
551A note on documentation
552</h3>
553<p>
554
555The "<tt>.txt</tt>" files documenting NTL's modules
556still reflect NTL's  Traditional mode.
557There should be no confusion in interpretting the meaning in ISO mode.
558Just remember: all of NTL is wrapped in namespace <tt>NTL</tt>,
559and the standard library is wrapped in namespace <tt>std</tt>.
560
561
562<p>
563<h3>
564Further changes in NTL version 4.1
565</h3>
566<p>
567
568The ISO Standard for <tt>C++</tt> is not compatible with the
569language defined in the second edition of Stroustrup's <tt>C++</tt> book.
570This is in fact quite annoying.
571Besides introducing namespaces, several modifications were made
572in version 4.1 that will allow NTL to be compiled smoothly under
573<i>either</i> the old or the new definition of the language
574(or any reasonable approximation thereof).
575These changes do not affect the (documented) NTL interface,
576and so version 4.1 should be backward compatible.
577<p>
578Here is a summary of the other changes:
579<ul>
580<li>
581Got rid of all <tt>friend</tt> functions.
582It turns out that new <tt>C++</tt> and old <tt>C++</tt> disagree
583quite strongly about the semantics of a <tt>friend</tt> function
584declaration.
585In getting rid of these, I also made a number of fields public
586which used to be private, but to prevent accidental misuse,
587I gave them strange names (e.g., the previously
588private member <tt>rep</tt> in class <tt>ZZ_p</tt>
589is now the public member <tt>_ZZ_p__rep</tt>).
590
591<p>
592This change is effective in both Traditional and ISO modes.
593
594<p>
595In my view, the ISO committee really committed an act of sabotage here.
596Now the <tt>friend</tt> mechanism is much more awkward than before,
597which makes the use of private members more awkward,
598which simply encourages programmers (like me) to avoid them altogether.
599
600<p>
601
602<li>
603When <tt>NTL_STD_CXX</tt> or <tt>NTL_PSTD_NTN</tt> are set,
604all calls to <tt>new</tt>
605have been replaced by <tt>new(std::nothrow)</tt>.
606
607<p>
608The ISO committee also committed an act of sabotage when they changed
609the semantics of the memory allocation operator <tt>new</tt>.
610In old <tt>C++</tt>, a memory allocation error simply returned
611a null pointer; in new <tt>C++</tt> an exception is thrown.
612The old semantics are available via  <tt>new(std::nothrow)</tt>.
613
614<p>
615You may of course use NTL in Traditional mode with a compiler that
616implements the new semantics for <tt>new</tt>.
617In this case, if the memory allocation fails, an exception will
618be thrown, and assuming you don't catch it, you will simply get an
619error message that is less informative than the one NTL would
620have printed.
621Also, your compiler may have a backward compatatibilty flag to
622use the old <tt>new</tt> semantics.
623
624<p>
625
626<li>
627Various and sundry other small changes, such as fixing
628occurrences of the
629the "<tt>log(2)</tt>" problem mentioned above.
630
631</ul>
632
633<p>
634
635
636<p>
637<h3>
638Standard C++ and the Real World
639</h3>
640
641<p>
642At the time of this writing, I know of no compiler that actually
643implements the new <tt>C++</tt> standard.
644Some come closer than others.
645
646<p>
647The compiler that comes the closest is
648the one available (for a price) from
649<a href="http://www.kai.com">www.kai.com</a>.
650One of the things it does not do correctly is that the global
651namespace is partially polluted with some function names from the standard
652<tt>C</tt> library, even if you use header files that are supposed
653to wrap them in namespace <tt>std</tt> (these names are also
654in namespace <tt>std</tt>).
655Besides this problem, and the fact there are a couple of <i>very</i>
656esoteric language features not yet implemented, the <i>KAI</i>
657compiler does a reasonable job.
658
659<p>
660I used this compiler (version 3.4g,  with the "--strict" flag)
661to make sure NTL
662worked correctly under the new standard (which was not entirely trivial),
663in either Traditional or ISO mode.
664
665<p>
666NTL also compiles correctly in in either Traditional or ISO
667mode using recent versions of the <i>GNU</i> compiler (which is free);
668I checked it with <i>egcs-2.91.66</i> and <i>gcc-2.95.2</i>.
669This compiler is still some distance
670from implementing standard <tt>C++</tt>, but is getting closer.
671There are several language features that are not yet implemented
672correctly, and also the <i>entire</i> contents of the standard <tt>C++</tt>
673library are visible in the global namespace (as well as namespace <i>std</i>).
674Nevertheless, NTL can still be used in ISO mode with the
675<i>GNU</i> compiler,
676as long as one is aware of the limitations of this compiler.
677
678<p>
679It has also been reported that
680NTL compiles correctly in ISO mode using the
681Metroworks CodeWarrior Pro 5, v. 5.3 compiler on a PowerMac 7500 running
682on a 200MHz 604e.
683
684<p>
685NTL cannot be used with Microsoft Visual C++ versions 5 or 6
686in ISO mode, although this compiler still works with NTL in Traditional mode.
687I have tested NTL with  Microsoft Visual C++ version 6,
688and found that one can use the <tt>NTL_PSTD_NNS</tt> to useful effect,
689especially if one wants to use the STL.
690So one can wrap NTL in a namespace.
691However, the <tt>NTL_PSTD_NHF</tt> still does not work:
692MSVC++ 6 is very inconsistent about the location of a number of
693names; even when one uses the new header files, some names
694in the standard library are in namespace <tt>std</tt>,
695while others are in the global namespace.
696Further, it appears that Koenig lookup is not properly
697implemented in MSVC++ 6, but luckily, NTL does not rely on this.
698
699<p>
700I do not yet know how NTL in ISO mode works on other compilers.
701Feedback is always welcome.
702
703<p>
704As usual,
705NTL should continue to work in Traditional mode on just about any
706available <tt>C++</tt> compiler.
707
708<p>
709
710
711
712
713<center>
714<a href="tour-modules.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a>
715 <a href="tour.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> 
716<a href="tour-unix.html"> <img src="arrow3.gif" alt="[Next]" align=bottom></a>
717</center>
718</body>
719</html>
Note: See TracBrowser for help on using the repository browser.