2013/3/29 Vlad from Moscow <
vlad....@mail.ru>:
>>> > According to the C++ Standard constructor
>>> > basic_string(size_type n, charT c, const Allocator& a = Allocator());
>>> > requires that n will be less than npos.
>>> > I tried a simple code
>>> > #include <string>
>>> > #include <climits>
>>> > int main()
>>> > {
>>> > std::string s( INT_MAX + ( std::string::size_type )1, 'A' );
>>> > }
>>> > using MS VC++ 2010 and GCC 4.7.2 compilers and always got an exception.
>>> > The MS VC++ 2010 reports an exception when it tries to allocate memory
>>> > in some internal function. The GCC reports exception "std::length_error"
>>> > INT_MAX + ( std::string::size_type )1 is less than std::string::npos
>>> > nevertheless the code aborts.
>>> > Is it a bug of all C++ compilers or I missed something?
[..]
>>> I used online compiler GCC 4.7.2 at
www.ideone.com
>>> sizeof( std::string::size_type ) is equal to 4.
>>> I was wondered that the both compilers, MS VC++ 2010 and GCC 4.7.2,
>>> issued an exception. Moreove GCC 4.7.2 reports exception
>>> 'std::length_error'' so it means that it makes some check for parameter n
>>> inside the constructor.
The compiler behaviour looks conforming to me. I extended the output
of your program as follows:
#include <string>
#include <climits>
#include <iostream>
#include <exception>
#include <typeinfo>
int main()
{
std::cout << "npos: " << std::string::npos << std::endl;
std::cout << "imax: " << std::string::size_type(INT_MAX +
(std::string::size_type )1) << std::endl;
std::string s0;
std::cout << "maxsize: " << s0.max_size() << std::endl;
try {
std::string s( INT_MAX + ( std::string::size_type )1, 'A' );
} catch(const std::exception& e) {
std::cout << "Type: " << typeid(e).name() << " what:" <<
e.what() << std::endl;
}
}
When I run it on the compiler you mentioned I got the following output:
npos: 4294967295
imax:
2147483648
maxsize: 1073741820
Type: St12length_error what:basic_string::_S_create
In [string.require] p1 we find:
"If any operation would cause size() to exceed max_size(), that
operation shall throw an exception object
of type length_error."
This is exactly what happens here.
Now when I run it on my Visual Studio VS2012 I get
npos: 4294967295
imax:
2147483648
maxsize: 4294967294
So we have no violation of max_size() here. But this behaviour is
still conforming, because it falls under a general "resource-limits"
clause from [res.on.exception.handling] p4:
"Any other functions defined in the C++ standard library that do not
have an exception-specification may throw implementation-defined
exceptions unless otherwise specified.(footnote 191: In particular,
they can report a failure to allocate storage by throwing an exception
of type bad_alloc, or a class derived from bad_alloc (18.6.2.1).
Library implementations should report errors by throwing exceptions of
or derived from the standard exception classes (18.6.2.1, 18.8,
19.2).)"
- Daniel