Previous | Contents | Index |
The C++ Standard Library provided with this release defines a complete specification of the Final Draft International ANSI C++ Standard (FDIS), with some differences, as described in the DIGITAL C++ Version 6.0 Release Notes for DIGITAL UNIX Systems.
The Standard Library in this release includes for the first time the ANSI locale and iostream libraries.
Note that portions of the ANSI C++ Standard Library have been implemented in DIGITAL C++ using source licensed from and copyrighted by Rogue Wave Software, Inc. Information pertaining to the C++ Standard Library has been edited and incorporated into DIGITAL C++ documentation with permission of Rogue Wave Software, Inc. All rights reserved.
Some of the components in the C++ Standard Library are designed to replace nonstandard components that are currently distributed in the DIGITAL C++ Class Library. DIGITAL will continue to provide the DIGITAL C++ Class Library in its nonstandard form. However, you now have the option of using new standard components.
The following sections provide more information on the DIGITAL C++
implementation of the Standard Library, including upward compatibility,
compiling, linking, and thread safety.
7.1 Important Compatibility Information
Because the standardization process for the C++ Standard Library is not yet completed, DIGITAL cannot guarantee that this version of the library is compatible with any past or future releases. We ship the run-time portion of the library in object form, not in shareable form, to emphasize this situation.
The following sections describe specific compatibility issues.
7.1.1 -[no]using_std Compiler Compatibility Switch
All standard library names in DIGITAL C++ are inside the namespace std. Typically you would qualify each standard library name with std:: or put using namespace std; at the top of your source file.
To make things easier for existing users, using namespace std; is included in a file provided with every standard library header when you are in arm, cfront, ms, or ansi compiler modes. This is not the default in strict_ansi or strict_ansi_errors mode.
The compiler supplied switches -nousing_std and -using_std can be used to override the default.
-nousing_std turns the implicit using
namespace std off; -using_std turns it on.
7.1.2 pre-ANSI/ANSI IOStreams Compatibility
The C++ Standard Library offers support for the standard IOStreams library based on the Final Draft International ANSI C++ Standard (FDIS). These standard iostream classes are in the new header files <iostream>, <ostream>, <istream>, and so on (no .h or .hxx extension). For backward compatibility, the pre-ANSI IOStream library is still provided in the old header files iostream.hxx, istream.hxx, and so on. The two libraries exhibit subtle differences and incompatibilities. Users can choose which version (ANSI or pre-ANSI) of iostreams they want to use; either version of iostreams can be integrated seamlessly with the new Standard Library and string functionality.
To accomplish this goal, macros called __USE_STD_IOSTREAM and
__NO_USE_STD_IOSTREAM are provided. If
you do not set these macros explicitly, the default in arm, cfront,
ms, and ansi modes is to use the pre-ANSI IOStream
library. In strict_ansi and strict_ansi_errors mode, the default is to use
the ANSI IOStream library.
You override the default by defining __USE_STD_IOSTREAM or
__NO_USE_STD_IOSTREAM on either the
command line or in your source code.
In arm, cfront, ms, and ansi modes, specify use of the ANSI iostreams in one of the following ways:
In strict_ansi and strict_ansi_errors modes specify use of the pre-ANSI iostreams in one of the following ways:
You will receive a #error warning if you have explicitly included the wrong header for the mode you are in. For example, if you say #include <iostream> (an ANSI header) and you are in -std ansi, -std cfront, -std ms or -std arm mode, and if you have not entered -D__USE_STD_IOSTREAM on the command line, you will receive an error. Similarly if you are in -std strict_ansi or -std strict_ansi_errors, and you enter #include <iostream.h>, you will receive an error unless you also enter -D__NO_USE_STD_IOSTREAM.
Many of the other headers, <string> for example, make use of the iostream classes. The default version of iostreams that is automatically included when you include one of these headers depends on the mode you compile in and the setting of the macros __USE_STD_IOSTREAM and __NO_USE_STD_IOSTREAM as described earlier. Because the standard locale class and the standard iostream class are so closely tied, you cannot use the standard locale class with the pre-standard iostream classes. If you want to use locale, you must use the standard iostream classes.
It is possible to use the pre-ANSI and the ANSI IOStream library in the same source file, because all the standard iostream names (that is, cout, cin, and so on) are in namespace std, and all the pre-ANSI names are in the global namespace. This is not recommended, though, because there is no guarantee of stream objects being the same size or, for example, of ::cout being in sync with std::cout.
To do this in all modes, include a pre-ANSI iostreams header before an ANSI iostreams header as follows:
#undef __USE_STD_IOSTREAM #include <iostream.h> #define __USE_STD_IOSTREAM #include <iostream> int main() { std::string s("abc"); ::cout << "abc" << endl; // pre-standard iostreams std::cout << "abc" << std::endl; // standard iostreams return 0; } |
To do this in all modes, if you include an ANSI iostreams header before a pre-ANSI iostreams header, follow these steps:
// Compile this with -nousing_std #define __USE_STD_IOSTREAM #include <iostream> #undef __USE_STD_IOSTREAM #include <iostream.h> #define __USE_STD_IOSTREAM // so the template definition files are ok int main() { std::string s("abc"); ::cout << "abc" << endl; // pre-standard iostreams std::cout << "abc" << std::endl; // standard iostreams return 0; } |
The Standard C++ Library supports the ANSI implementation of the operator new() as well as the pre-ANSI implementation of operator new(). The ANSI implementation throws std::bad_alloc on memory allocation failures. The pre-ANSI implementation of the operator new() returns 0 on memory allocation failures. Because the ANSI behavior is incompatible with pre-ANSI applications, a compile time switch has been added (-[no]stdnew) to control whether calls to ANSI new() or pre-ANSI new are generated.
The following examples show how ANSI versus pre-ANSI new() check for memory allocation. First, here is an ANSI new() check for memory allocation failure:
try { myobjptr = new (myobjptr); } catch (std::bad_alloc e) { cout << e.what() << endl; }; |
The following example shows a pre-ANSI new() check for memory allocation failure:
if ((myobjptr = new (myobjptr)) == 0) call_failure_routine(); |
When upgrading pre-ANSI new() code to work with the C++ Standard Library you also can use the nothrow version of ANSI new(). To do so in the pre-ANSI example, you could recode it as follows:
if ((myobjptr = new (myobjptr, nothrow)) == 0) call_failure_routine(); |
Two command line switches are available in the compiler to control whether calls are generated to the ANSI or pre-ANSI implementation of operator new(). Use the -stdnew switch to generate calls to the ANSI new() implementation. Use the -nostdnew switch to generate calls to the pre-ANSI new() implementation. Note that you can override global new() by declaring your own functions.
When compiling with -std ansi, -std strict_ansi, and -std
strict_ansi_errors, -stdnew
is the default. When compiling with -std
arm, -std cfront, and -std ms, -nostdnew is the default. The compiler defines
the macro __STDNEW when the -stdnew option is specified.
7.1.4 Support for Global array new and delete Operators
DIGITAL C++ Version 6.0 fully supports the array new and delete operators as described in the ANSI standard. Previous versions did not.
You might therefore encounter a compatibility problem if you have overridden the run-time library's operator new() with your own version.
For example:
#include <iostream.h> inline void* operator new(size_t s) { cout << "called my operator new" << endl; return 0; } void main() { new int; // ok, this still calls your own new int[4]; // In V6.0 calls the C++ library's operator new[] } |
In older versions, both new int and new int[4] would generate a call to operator new() (they would just be asking for different sizes). With the current compiler, new int still generates a call to operator new(). However, new int[4] generates a call to operator new()[]. This means that if you still want to override the library's operator new you must do one of the following:
The -noglobal_array_new switch converts all expressions such as new int[4] to calls to the global operator new(), thus preserving compatibility with older compiler versions.
Note that this switch has no effect on class-specific array operator new and delete; it affects only the global operators.
When compiling with -std ansi, -std strict_ansi, -std
strict_ansi_errors, and -std ms
modes, -global_array_new is
the default. When compiling with -std arm
or -std cfront modes, -noglobal_array_new is the default. A macro
__GLOBAL_ARRAY_NEW is predefined by the
compiler when -global_array_new is used.
7.2 How to Build Programs Using the C++ Standard Library
When you use the cxx command to compile and link programs that use the C++ Standard Library, no special switches are required. The DIGITAL C++ driver automatically includes the Standard Library run-time support (-lcxxstd) on the link command, and automatic template instantiation (-pt) is the default mode.
For example, to build a program called prog.cxx that uses the Standard Library, you can simply use the following command:
cxx prog.cxx |
The Standard Library provided with this release is thread safe but not thread reentrant. Thread safe means that all library internal and global data is protected from simultaneous access by multiple threads. In this way, internal buffers as well as global data like cin and cout are protected during each individual library operation. Users, however, are responsible for protecting their own objects. |
The inplace_merge, stable_sort, and stable_partition algorithms require the use of a temporary buffer. Two methods are available for allocating this buffer:
By default, the current DIGITAL C++ library makes use of the preallocated buffer, which avoids the overhead of run-time allocation. If your application requires a buffer that exceeds 16K, it can not take advantage of this default.
If you are concerned with minimizing the use of stack space in your program, or if your application requires a buffer that exceeds 16K, define the __DEC_DYN_ALLOC macro to enable dynamic buffering. Do this by adding the following to your compile command line:
-D__DEC_DYN_ALLOC |
The following discussion guides you through upgrading the DIGITAL C++
Class Library code to use the Standard Library, specifically replacing
the vector and stack classes in the vector.hxx header file to the Standard Library
vector and stack classes.
7.4.1 Upgrading from the DIGITAL C++ Class Library Vector to the Standard Library Vector
To change your code from using the DIGITAL C++ Class Library vector to the Standard Library vector, consider the following actions:
Nonstandard Vector Function | Standard Library Vector Function |
---|---|
elem(int index) |
operator[](size_t index)
(no bounds checking) |
operator[](int index) |
at(size_t index)
(bounds checking) |
setsize(int newsize) | resize(size_t newsize) |
To change your code from using the existing stack to the Standard Library stack, consider the following actions:
Class Library Stack | Standard Library Stack |
---|---|
size_used() | Does not exist because the size() function always is equal to the size_used() function. |
full() | Does not exist because the stack always is full. |
pop() |
Does not return the popped element. To simulate DIGITAL C++ Class
Library behavior, first obtain the element as the return type from the
top()
function and then call the
pop()
function. For example, change
int i=s.pop();
to the following:
int i=s.top(); |
The Standard basic_string library can replace the DIGITAL C++ Class Library String Package.
The following list guides you through upgrading nonstandard code to use the Standard Library basic_string:
string s("abc"); char* cp = s; // not allowed const char* cp = s.data(); // ok |
template <class charT, class traits, class Allocator> inline basic_string<charT, traits, Allocator> upper(const basic_string<charT,traits, Allocator>& str) { basic_string<charT, traits, Allocator> newstr(str); for (size_t index = 0; index < str.length(); index++) if (islower(str[index])) newstr[index] = toupper(str[index]); return newstr; } template <class charT, class traits, class Allocator> inline basic_string<charT, traits, Allocator> lower(const basic_string<charT,traits, Allocator>& str) { basic_string<charT, traits, Allocator> newstr(str); for (size_t index = 0; index < str.length(); index++) if (isupper(str[index])) newstr[index] = tolower(str[index]); return newstr; } |
s2 = s1.upper(); // does not compile s2 = upper(s1); // ok |
string s1("abcdef"); string s2("abcdgf"); assert(s1.match(s2)==4); // does not compile pair<string::iterator,string::iterator> p(0,0); // ok p=mismatch(s1.begin(),s1.end(),s2.begin()); assert(p.first-s1.begin()==4); string s3 = s1; p=mismatch(s1.begin(),s1.end(),s3.begin()); assert(p.first == s1.end()); // everything matched |
string s("abcde"); string s2 = s1(1,3); // does not compile string s2 = s1.substr(1,3); // ok |
Previous | Next | Contents | Index |