This article discusses the differences among three libraries and explores the situations in which one library is preferred over another.
For use in -compat=5
or -std=sun03
mode, the Oracle Developer Studio C++ compiler can make use of any of three implementations of the C++ standard library: libCstd
, libstlport
, and libstdcxx
.
libCstd
is used by default and is based on Rogue Wave's stdlib 2.1.1
.libstlport
is based on STLport version 4.5.3 and is used if you specify the compiler option -library=stlport4
.libstdcxx
is based on the Apache Standard C++ open source library version 4, and is used if you specify the compiler option -library=stdcxx4
.The Oracle Developer Studio C++ compiler started shipping with the standard C++ library libCstd
in the C++ 5.0 release of December 1998. Some of the newer language features such as member template classes, member template functions and partial specializations were not yet implemented in the compiler even though the C++ standard library uses all these language features. The libCstd
headers use macros to enable or disable functionality in the library that rely on these features and the macros were defined to disable the functionality that uses the missing language features.
Later versions of the compiler implemented the new language features. However, in order to maintain binary compatibility with existing object files, the macros in the libCstd
headers were not modified. As a result, the latest version of libCstd
continues to have some missing functionality, and some of the functions accept a different set of arguments than those that are specified in the standard.
The libstlport
library was introduced in the C++ 5.4 release and uses all the language features needed by the library.
Support for the libstdcxx
library was introduced in the C++ 5.10 release, and uses all the language features needed by the library.
No library functionality is suppressed in libstlport
or libstdcxx
because of missing language features. These libraries, therefore, conform more closely to the standard than does libCstd
.
libCstd
This section lists the different language features that are disabled in libCstd
along with the corresponding missing functionality. Small test examples illustrate the missing features. The compiler issues errors for each test case if the default libCstd
is used. All the test cases compile without errors using libstlport
or libstdcxx
. Workarounds using the existing libCstd
functionality are provided wherever possible.
Note: The following macros defined in the libCstd
header stdcomp.h
are used to disable functionality:
_RWSTD_NO_MEMBER_TEMPLATES
_RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
_RWSTD_NO_CLASS_PARTIAL_SPEC
Do not redefine any macro whose name starts with _RWSTD, because doing so can result in a program that won't compile, won't link, or won't run correctly. The reason for such problems is that the headers that are seen by a user program must match the headers that were used to build the libCstd
that is linked to the program. By redefining the macro, you introduce an inconsistency between the way the library was built and the way it's being used.
The macro _RWSTD_NO_MEMBER_TEMPLATES
is defined in libCstd
to indicate that member template functions are not supported, and the macro _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
is defined to indicate that the compiler does not support the syntax for functions that are templatized only on the return type. As a result, the following functions are missing.
Missing Members of Class complex
in <complex>
template <class X> complex<T>& operator= (const complex<X>& rhs);
template <class X> complex<T>& operator+= (const complex<X>& rhs);
template <class X> complex<T>& operator-= (const complex<X>& rhs);
template <class X> complex<T>& operator*= (const complex<X>& rhs);
template <class X> complex<T>& operator/= (const complex<X>&);
Example
The following test case does not compile with libCstd
:
% cat c1.c
#include <complex>
using namespace std;
struct X {
X() : d(0.0) { }
X(double x) : d(x) { }
X& operator +=(double y) { d += y; return *this; }
double d;
};
int main()
{
const complex<double> d1(1.0, 2.0);
const complex<double> d2(3.0, 4.0);
complex<X> d3;
d3 = d1; // line 16
d3 += d2; // line 17
}
% CC c1.c
"c1.c", line 15: Error: Cannot assign const std::complex<double> to
std::complex<X> without "std::complex<X>::operator=(const std::complex<X>&)";.
"c1.c", line 16: Error: The operation "std::complex<X> += const
std::complex<double>" is illegal.
2 Error(s) detected.
% CC -library=stlport4 c1.c
%
Replace the lines
complex<X> d3;
d3 = d1;
d3 += d2;
with
complex<double> temp = d1;
temp += d2;
complex<X> d3(temp.real(), temp.imag());
Missing Members of Class basic_string
in <string>
In the list below, Typ
can be one of: int
, unsigned int
, long
, unsigned long
, short
, unsigned short
, char
, unsigned char
, wchar_t
, or bool
. An entry containing Typ
is actually ten entries with Typ
replaced by each of these types in turn.
template <class InputIterator> basic_string (InputIterator, InputIterator, const Allocator&);
basic_string (Typ n, charT c, const Allocator& alloc);
template<class InputIterator> basic_string<charT, traits, Allocator>& append (InputIterator, InputIterator);
basic_string<charT, traits, Allocator>& append (Typ n, charT c);
template<class InputIterator> basic_string<charT, traits, Allocator>& assign (InputIterator, InputIterator);
basic_string<charT, traits, Allocator>& assign (Typ n, charT c);
template<class InputIterator> void insert (iterator, InputIterator, InputIterator);
void insert (iterator p, Typ n, charT c);
template<class InputIterator> basic_string<charT, traits, Allocator>& __replace_aux (iterator first1, iterator last1, InputIterator first2, InputIterator last2);
template<class InputIterator> basic_string<charT, traits, Allocator>& replace (iterator, iterator, InputIterator, InputIterator);
basic_string<charT, traits, Allocator>& replace (iterator first, iterator last, Typ n, charT c);
Example
% cat s1.c
#include <string>
#include <list>
using namespace std;
int main()
{
string s1("abcd");
list<char> l1;
l1.push_back('e');
l1.push_back('f');
string s2 = s1.append( l1.begin(), l1.end() ); // line 11
}
% CC s1.c
"s1.c", line 11: Error: Could not find a match for std::string::append
(std::list<char>::iterator, std::list<char>::iterator) needed in main().
1 Error(s) detected.
Replace the line
string s2 = s1.append( l1.begin(), l1.end() );
with
string s2(s1);
for( list<char>::iterator i = l1.begin(); i != l1.end(); ++i )
s2 += *i;
Missing Member of Class pair
in <utility>
template<class U, class V> pair(const pair<U, V> &p);
Example
% cat p1.c
#include <utility>
struct S {
S() { val = 0; }
S(int i) { val = i; }
int val;
};
int main()
{
std::pair<int, int> p1(1, 2);
std::pair<S, int> p2 = p1; // line 12
}
% CC p1.c
"p1.c", line 12: Error: Cannot use std::pair<int, int> to initialize std::pair<S, int>.
1 Error(s) detected.
Replace the line
std::pair<S, int> p2 = p1;
with
std::pair<S, int> p2(p1.first, p1.second);
Missing members of class locale
in <locale>
// creating locale based on other locales:
template <class Facet> locale (const locale& other,Facet* f);
// assignment:
template <class Facet> locale combine(const locale& other);
// sorting of strings:
template <class charT, class Traits, class Allocator> bool operator() (const basic_string<charT,Traits,Allocator>& s1, const basic_string<charT,Traits,Allocator>& s2) const;
// facet access:
template <class Facet> const Facet& use_facet (const locale&); template <class Facet> inline bool has_facet (const locale&) throw();
Example
% cat l1.c
#include <locale>
using namespace std;
int main()
{
locale loc1("C");
locale loc2("de");
locale loc3 = loc1.combine<numpunct<char> >(loc2); // line 8
const time_get<char>& f = use_facet<time_get<char> >(loc1);
}
% CC l1.c
"l1.c", line 8: Error: Unexpected type name "std::numpunct<char>" encountered.
"l1.c", line 8: Error: combine is not a member of std::locale.
"l1.c", line 9: Error: Could not find a match for std::use_facet<std::Facet>
(std::locale) needed in main().
3 Error(s) detected.
Missing Members of Class bit_set
in <bitset>
template <class charT, class traits, class Allocator>
basic_string<charT,traits,Allocator> to_string () const;
Example
% cat b1.c
#include <bitset>
#include <iostream>
using namespace std;
int main()
{
bitset<7> b(4);
string s = b.to_string<char, char_traits<char>, allocator<char> >(); // line 7
cout << "s = " << s << endl;
}
% CC b1.c
"b1.c", line 7: Error: Badly formed expression.
. . .
and possibly additional error messages.
Replace the line
string s = b.to_string<char, char_traits<char>, allocator<char> >();
with
string s = b.to_string();.
The macro
_RWSTD_NO_CLASS_PARTIAL_SPEC is defined to indicate that the compiler does not support partial specialization of template classes with default parameters. As a result, the following global functions are missing in <algorithm>
.
count()
count_if()
Example
% cat c2.c
#include <algorithm>
#include <list>
#include <iostream>
#include <iterator>
using namespace std;
bool gtr3(int n)
{
return (n > 3);
}
int main()
{
// count elements in a list
list<int> x;
for (int i = 0; i < 10; i++)
x.push_back(i);
cout << "list: ";
copy (x.begin(), x.end(), ostream_iterator<int>(cout, " "));
cout << endl;
int n1 = count(x.begin(), x.end(), 6); // line 21
int n2 = count_if(x.begin(), x.end(), gtr3); // line 22
cout << "n1 = " << n1 << endl;
cout << "n2 = " << n2 << endl;
}
% CC c2.c
"c2.c", line 21: Error: Could not find a match for std::count<std::InputIterator, std::T, std::Size>
(std::list<int>::iterator, std::list<int>::iterator, int) needed in main().
"c2.c", line 22: Error: Could not find a match for std::count_if<std::InputIterator, std::Predicate, std::Size>
(std::list<int>::iterator, std::list<int>::iterator, bool(int)) needed in main().
2 Error(s) detected.
Replace the lines
int n1 = count(x.begin(), x.end(), 6); // # elements with value 6
int n2 = count_if(x.begin(), x.end(), gtr3); // # elements with value >3
with
int n1 = 0;
int n2 = 0;
count(x.begin(), x.end(), 6, n1); // # elements with value 6
count_if(x.begin(), x.end(), gtr3, n2); // # elements with value >3
Missing Template Classes in <iterator>
template <class Iterator> struct iterator_traits {}
template <class T> struct iterator_traits<T*> {}
template <class T> struct iterator_traits<const T*> {}
Example
% cat i1.c
#include <iterator>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> v(10);
for (int i = 0; i < 10; i++)
v[i] = i;
iterator_traits<int*>::value_type x = v[5]; // line 11
cout << "vector: ";
copy (v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << endl;
cout << "x = " << x << endl; // line 15
}
% CC i1.c
"i1.c", line 11: Error: iterator_traits is not defined.
"i1.c", line 11: Error: Badly formed expression.
"i1.c", line 15: Error: x is not defined.
3 Error(s) detected.
Replace the line
iterator_traits<int>::value_type x = v[5];
with
int x = v[5];
Historically, Oracle Developer Studio C++ used libCstd
by default. Depending on the compiler and OS version, the default library might be different. If binary compatibility with existing object files or libraries is required, and those object files or libraries were built using libCstd
, then libCstd
must be used for building the application. The drawback is that the application cannot use the features that are missing in libCstd
.
libstlport
provides an implementation that is much closer to the standard. If an application needs the functionality that is missing in libCstd
, then libstlport
can often be used.
Note 1: libstlport
does not have support for C++ locales, used for internationalization and localization of text input and output.
Note 2: The shared library libstlport.so.1
must be shipped as part of your application if you choose to use it. Unlike libCstd
and libstdcxx
, it is not provided as part of Oracle Solaris.
libstdcxx
provides a full implementation of the C++ Standard Library, including C++ locales. Ordinarily, this library is the preferred choice.
Note 1: libstdcxx
is available only on Oracle Solaris 10 updates 10 and 11, and on Oracle Solaris 11.
Note 2: Support for libstdcxx
is not available with compilers older than C++ 5.10.
Additional Considerations
-library
option: one of -library=Cstd
(the default), -library=stlport4
, or -library=stdcxx4
.libCstd
does not support all the features of the standard library.libstlport
conforms more closely to the C++ standard, but does not have support for C++ locales.libstdcxx
is a complete implementation of the C++ Standard Library.libCstd
is provided with all Oracle Solaris versions.libstlport
is not provided with Oracle Solaris. You must provide it with your application.libstdcxx
cannot be used with compilers earlier than C++ 5.10, and is not available on Oracle Solaris versions earlier than Oracle Solaris 10 update 10.