C++ Migration Guide |
Using Iostreams and Library Headers
This chapter explains the library and header file changes that were implemented in the C++ 5.0 compiler. You must consider these changes when migrating code that was intended for C++ 4 compilers for use with the Sun WorkShop 6 C++ compiler.
4.1 Iostreams
The C++ 4.2 compiler implemented classic iostreams, which never had a formal definition. The implementation is compatible with the version released with
Cfront
(1990), with some bug fixes.Standard C++ defines a new and expanded iostreams (standard iostreams). It is better defined, feature-rich, and supports writing internationalized code.
In compatibility mode, you get classic iostreams, the same version supplied with the C++ 4.2 compiler. Any existing iostream code that works with the 4.2 compiler should work exactly the same way when compiling in compatibility mode (
-compat[=4]
).
Note Two versions of the classic iostream runtime library are supplied with the compiler. One version is compiled with the compiler in compatibility mode, and is the same as the library used with C++ 4.2. The other version is compiled from the same source code, but with the compiler in standard mode. The source-code interface is the same, but the binary code in the library has the standard-mode ABI. See Section 1.3 "Binary Compatibility Issues".
In standard mode, you get standard iostreams by default. If you use the standard form of header names (without "
.h
"), you get the standard headers, with all declarations in namespacestd
.Four of the standard headers are also provided in a form ending with "
.h
" that makes the header names available in the global namespace via using-declarations.
<fstream.h>
<iomanip.h>
<iostream.h>
<strstream.h>
These headers are a Sun extension, and code that depends on them might not be portable. These headers allow you to compile existing (simple) iostream code without having to change the code, even though standard iostreams are used instead of classic iostreams. For example, CODE EXAMPLE 4-2 will compile with either classic iostreams or with the Sun implementation of standard iostreams.
CODE EXAMPLE 4-1 Using Standard iostream
Name Forms #include <iostream>int main(){std::cout << "Hello, world!" << std::endl;}
CODE EXAMPLE 4-2 Using Classic iostream
Name Forms #include <iostream.h>int main(){cout << "Hello, world!" << endl;}Not all classic iostream code is compatible with standard iostreams. If your classic iostream code does not compile, you must either modify your code or use classic iostreams entirely.
To use classic iostreams in standard mode, use the compiler option
library=iostream
on theCC
command line. When this option is used, a special directory is searched that contains the classic iostream header files, and the classic iostream runtime library is linked with your program. You must use this option on all compilations that make up your program as well as on the final link phase or you will get inconsistent program results.
Note Mixing old and new forms of iostreams--including the standard input and output streamscin
,cout
, andcerr
--in the same program can cause severe problems and is not recommended.
With classic iostreams, you can write your own forward declarations for iostream classes instead of including one of the iostream headers. For example:
This approach will not work for standard iostreams, because classic names (
istream
,ofstream
,streambuf
, and so forth) are not the names of classes in standard iostreams. They are typedefs referring to specializations of class templates.With standard iostreams, you cannot provide your own forward declarations of iostream classes. Instead, to provide correct forward declarations of the iostream classes, include the standard header
<iosfwd>
.
To write code that will work with both standard and classic iostreams, you can include the full headers instead of using forward declarations. For example:
4.2 Task (Coroutine) Library
The coroutine library, accessed through the
<task.h>
header, is no longer supported. Compared to the coroutine library, Solaris threads are better integrated into the language development tools (particularly the debugger) and the operating system.4.3 Rogue Wave Tools.h++
The Sun WorkShop 6 C++ compiler includes Rogue Wave
Tools.h++
version 7. The Rogue WaveTools.h
++ version 7 library is built with classic iostreams. Therefore, when you include the Rogue Wave tools library in standard mode, you must also includelibiostream
. You must be careful to not use the old and new forms of iostreams in the same program. When using Tools.h++ in standard mode, use the-library=iostream
option when compiling and linking everything in the complete program.
- To use the Rogue Wave
Tools.h++
libraries in standard mode, use the following compiler option:
-library=rwtools7,iostream
- To use the Rogue Wave
Tools.h++
libraries in compatibility mode, use the following compiler option:
-compat -library=rwtools7
Refer to the C++ User's Guide or the
CC
(1) man page for more information about accessingTools.h++
.4.4 C Library Headers
In compatibility mode, you use the standard headers from C as before. The headers are in the
/usr/include
directory, supplied with the Solaris version you are using.The C++ standard has changed the definition of the standard C headers.
For clarification, the headers being discussed are the 17 headers defined by the ISO C standard (ISO 9899:1990) plus its later addendum (1994):
<assert.h> <ctype.h> <errno.h> <float.h> <iso646.h><limits.h> <locale.h> <math.h> <setjmp.h> <signal.h><stdarg.h> <stdio.h> <stdlib.h> <string.h> <time.h><wchar.h> <wctype.h>The hundreds of other headers that reside in and below the
/usr/include
directory are not affected by this language change because they are not part of the C language standard.You can include and use any of these headers in a C++ program the same as in previous versions of Sun C++, but some restrictions apply.
The C++ standard requires that the names of types, objects, and functions in these headers appear in namespace
std
as well as in the global namespace. This in turn means that the versions of these headers supplied with the Solaris 2.6 and 7 operating environments cannot be used directly. If you compile in standard mode, you must use the versions of these headers that are supplied with the Sun WorkShop 6 C++ compiler. If you use the wrong headers, your program can fail to compile or link.With the Solaris 2.6 and 7 operating environments, you must use the standard spelling for the header, not a path name. For example, write:
#include <stdio.h> // Correctand not either of these:
#include "/usr/include/stdio.h" // Wrong#include </usr/include/stdio.h> // WrongWith the Solaris 8 operating environment, the standard C headers in
/usr/include
are correct for C++, and are used by the C++ compiler automatically. That is, if you write
#include <stdio.h>you will get the C++ compiler's version of
stdio.h
when compiling on the Solaris 2.6 and 7 operating environments, but the Solaris version ofstdio.h
when compiling on the Solaris 8 operating environment. With the Solaris 8 operating environment, there is no restriction against using the explicit path name in the include statement. However, use of path names, such as</usr/include/stdio.h>
, does make the code unportable.The C++ standard also introduces a second version of each of the 17 standard C headers. For each header of the form
<NAME.h>
, there is an additional header of the form<cNAME>
. That is, the trailing ".h
" is dropped, and a leading "c
" is added. Some examples:<cstdio>
,<cstring>
,<cctype>
.These headers contain the names from the original form of the header but appear only in namespace
std
. An example of use according to the C++ standard is:
#include <cstdio>int main() {printf("Hello, "); // Error, printf unknownstd::printf("world!\n"); // OK}Because the code uses
<cstdio>
instead of<stdio.h>
, the nameprintf
appears only in namespacestd
and not in the global namespace. You must either qualify the nameprintf
, or add a using-declaration:
#include <cstdio>using std::printf;int main() {printf("Hello, "); // OKstd::printf("world!\n"); // OK}The standard C headers in
/usr/include
contain many declarations that are not allowed by the C standard. The declarations are there for historical reasons, primarily because UNIX systems have traditionally had the extra declarations in those headers, or because other standards (like POSIX or XOPEN) require them. For continued compatibility, these extra names appear in the Sun C++ versions of the<NAME.h>
headers, but only in the global namespace. These extra names do not appear in the<cNAME>
versions of the headers.Because these new headers have never been used in any previous program, there is no compatibility or historical issue. Consequently, you might not find the
<cNAME>
headers to be useful for general programming. If you want to write maximally portable standard C++ code, however, be assured that the<cNAME>
headers do not contain any unportable declarations. The following example uses<stdio.h>
:
#include <stdio.h>extern FILE* f; // std::FILE would also be OKint func1() { return fileno(f); } // OKint func2() { return std::fileno(f); } // ErrorThe following example uses
#include <cstdio>extern std::FILE* f; // FILE is only in namespace stdint func1() { return fileno(f); } // Errorint func2() { return std::fileno(f); } // Error<cstdio>
:Function
fileno
is an extra function that for compatibility continues to appear in<stdio.h>
, but only in the global namespace, not in namespacestd
. Because it is an extra function, it does not appear in<cstdio>
at all.
Note The Sun WorkShop 6 C++ compiler's versions of the<wchar.h>
,<cwchar>
,<wctype.h>
, and<cwctype>
header files for the Solaris 2.6 operating environment are missing some functions because the Solaris 2.6 environment does not provide the capabilities required by the functions.
The C++ standard allows using both the
<NAME.h>
and<cNAME>
versions of the standard C headers in the same compilation unit. Although you probably would not do this on purpose, it can happen when you include, for example,<cstdlib>
in your own code, and some project header you use includes<stdlib.h>
. On Solaris 2.6 operating environments, this mixing does not work for some headers, particularly for the<wchar.h>
/<cwchar>
and<wctype.h>
/<cwctype>
header pairs. If you get compiler complaints about one of these headers, use the<NAME.h>
version of the header in your code instead of the<cNAME>
version.4.5 Standard Header Implementation
The C++ User's Guide explains in detail how standard headers are implemented along with the reasons for the implementation method. When you include any of the standard C or C++ headers, the compiler actually searches for a file with the specified name suffixed by "
.SUNWCCh
". For example,<string>
causes a search for<string.SUNWCCh>
and<string.h>
causes a search for<string.h.SUNWCCh>
. The compiler'sinclude
directory contains both spellings of the names, and each pair of spellings refers to the same file. For example, in directoryinclude/CC
you find bothstring
andstring.SUNWCCh
. They refer to the same file, the one you get when you include<string>
.In error messages and debugger information, the suffix is suppressed. If you include
<string>
, error message and debugger references to that file mentionstring
. File dependency information uses the namestring.SUNWCCh
to avoid problems with default makefile rules regarding unsuffixed names. If you want to search for just header files (using thefind
command, for example) you can look for the.SUNWCCh
suffix.
Sun Microsystems, Inc. Copyright information. All rights reserved. Feedback |
Library | Contents | Previous | Next | Index |