On Fri, 10 Dec 2021 at 17:17, Jakub Jelinek wrote: > > On Fri, Dec 10, 2021 at 10:11:04AM -0700, Martin Sebor via Gcc-patches wrote: > > On 12/10/21 9:41 AM, Jakub Jelinek wrote: > > > On Fri, Dec 10, 2021 at 09:35:50AM -0700, Martin Sebor via Gcc-patches > > > wrote: > > > > The above was just a quick proof of concept experiment. You're > > > > of course right that the final solution can't be so crude(*). > > > > But if the required functions are always_inline (I think member > > > > functions defined in the body of the class implicitly are > > > > > > They are not, and can't be, nothing says that such member functions > > > can't use constructs that make it uninlinable (with always_inline > > > that would be an error), or are way too large that inlining is not > > > desirable, etc. They are just implicitly inline. > > > > The functions we're talking about are the trivial max_size() > > members of std::string and allocator traits. They just return > > a constant. > > > > But I see I was wrong, even member functions have to be explicitly > > declared always_inline to be guaranteed to be inlined even at -O0. > > I don't think that should be an issue for the trivial max_size() > > (at least not for the std::string specialization). > > Note, if those functions are declared constexpr, without -fno-inline > (default at -O0), then cp_fold will try to evaluate such calls to constant > expressions already, effectively "inlining" them.
Every member function of std::string is constexpr in C++20, but not before. But we could add constexpr to internal _M_xxx functions if that benefits optimization. For std::basic_string::max_size() it has to call another function provided by the allocator, but for the std::string (i.e. std::basic_string<char, char_traits<char>, allocator<char>>) specialization we know what the allocator is going to tell us. --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -1071,7 +1071,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _GLIBCXX20_CONSTEXPR size_type max_size() const _GLIBCXX_NOEXCEPT - { return (_Alloc_traits::max_size(_M_get_allocator()) - 1) / 2; } + { + if _GLIBCXX17_CONSTEXPR (__are_same<allocator_type, allocator<char>>) + return size_t(-1) / 2; + else + return (_Alloc_traits::max_size(_M_get_allocator()) - 1) / 2; + } /** * @brief Resizes the %string to the specified number of characters.