What are acceptable values for the parameter size_type n in std::string constructors?

109 views
Skip to first unread message

Vlad from Moscow

unread,
Mar 28, 2013, 4:25:07 PM3/28/13
to std-dis...@isocpp.org
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?

Marshall Clow

unread,
Mar 28, 2013, 5:29:08 PM3/28/13
to std-dis...@isocpp.org
Most implementations will allocate memory to hold 'n' (+1?) "characters".
I suspect that you're getting an "out of memory" exception.

On my system, (Mac OS X 10.8.3, 8 GB ram), INT_MAX == 2147483647 and your code terminates normally (does not throw an exception).

-- Marshall

J. Daniel Garcia

unread,
Mar 28, 2013, 6:00:01 PM3/28/13
to std-dis...@isocpp.org
Are you using 32 or 64 bits?

Under 64 bits gcc 4.7.2 does not throw.

By the way, which is sizeof(std::string::size_type) under your implementation?



--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussio...@isocpp.org.
To post to this group, send email to std-dis...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/?hl=en.






Vlad from Moscow

unread,
Mar 29, 2013, 2:04:48 AM3/29/13
to std-dis...@isocpp.org
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.
 




Daniel Krügler

unread,
Mar 29, 2013, 7:14:52 AM3/29/13
to std-dis...@isocpp.org
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
Reply all
Reply to author
Forward
0 new messages