34

std::string provides a max_size() method to determine the maximum number of elements it can contain.

However, to work out the maximum length of a string in general, the programmer has to create a (possibly empty) string object.

If this class doesn't need any information from the programmer, why isn't max_size() available as a compile-time constant ? Is there some kind of runtime information necessary for a string to work out its maximum size ?

slaphappy
  • 6,894
  • 3
  • 34
  • 59
  • 1
    Youre logic of needing to create an empty string does not hold (because the underlying allocator holds this info). Also max_size() is not a constant value. It is the largest value that can be allocated currently (which is runtime dependent on the state of the allocator). – Martin York Oct 30 '12 at 15:29
  • @Loki: Can you provide a reference for your statement? I ask because I am pretty sure you are wrong (for `max_size` as applied to strings; allocators are a different story). – Nemo Oct 30 '12 at 22:23
  • 1
    @Nemo: There is nothing in the standard that says it is constant. It may well be constant in some implementations though. (**I am assuming here** -> ) If the standard committee had wanted it to be a constant they would have made it a const member variable like `std::string::npos` but to provide the more opportunity for flexibility it is a method. – Martin York Oct 30 '12 at 23:22
  • @LokiAstari: "If the standard committee had wanted it... they would have..." I guess you weren't around when they forgot to declare `std::vector`'s memory contiguous. And what about exception specifications? They are no gods, they make errors. The C++03 standard only says (23.1) "`size()` of the largest possible container" and that it should have O(1). That's quite vague, IYAM, and leaves a lot of room for speculation as to what it was meant for. – sbi Nov 01 '12 at 20:34

4 Answers4

22

One reason is that the max_size function isn't very useful at all, and the committee doesn't think it is worth the trouble to try to fix it. So it is just left the way it is, because it is part of the documented interface.

See library defect report #197:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3440.html#197

max_size() isn't useful for very many things, and the existing wording is sufficiently clear for the few cases that max_size() can be used for. None of the attempts to change the existing wording were an improvement.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
  • 1
    +1. It's a pretty useless function indeed. What `std::string::max_size()` returns is _this is the maximum string length it could possibly hold if one had enough memory_. Surprised so many incorrect answers here. – Maxim Egorushkin Oct 30 '12 at 13:22
  • And despite this [std::string::max_size()](https://en.cppreference.com/w/cpp/string/basic_string/max_size) *was* made constexpr in C++20. – BoP Jul 27 '23 at 18:22
18

std::string::max_size() calls std::allocator::max_size() under the hood.

According to the standard, 20.9.6.1.10:

size_type max_size() const noexcept;

Returns: The largest value N for which the call allocate(N,0) might succeed.

(See also: allocator::max_size)

Theoretically, an allocator implementation could be able to work out the maximum size of a chunk of memory it could allocate via a syscall. This would help determine the largest possible size for a string, inside a specific process.

Community
  • 1
  • 1
slaphappy
  • 6,894
  • 3
  • 34
  • 59
  • 6
    The standard does _not_ require string's `max_size` to call the allocator's `max_size`. The standard's description for `string` refers to "container requirements" in section 23.1, which defines `max_size` as "`size()` of the largest possible container". It does not refer to allocators at all, so this answer is simply wrong. – Nemo Oct 30 '12 at 22:25
5

The call to max_size() is delegated to the allocator used for the container.

In theory, a very smart allocator could compute its max_size in runtime, e.g. depending on RAM available.

Andriy
  • 8,486
  • 3
  • 27
  • 51
  • 1
    No, it is _not_ delegated to the allocator according to the standard. Perhaps it is in your particular implementation, but that is irrelevant. Cite where the spec says anything about the container delegating this call to its allocator and I will remove my downvote. – Nemo Oct 30 '12 at 22:28
  • @Nemo: Yes, `string::max_size()` is not required to do so by the standard. I was talking about a possible implementation. – Andriy Oct 31 '12 at 07:05
0

This should also work:

enum : std::string::size_type {
    npos     = std::string::size_type(-1),
    max_size = npos - 1
};
StackedCrooked
  • 34,653
  • 44
  • 154
  • 278