r/cpp•
tuskcode

Status of p0506r0 - use string_view for library function parameters....

I just had a lightbulb moment, thinking that the acceptance of string_view as parameters for std library functions would be great. As it turns out, Peter Sommerlad has already had this brain wave and has developed a proposal. Does anybody know the status of this paper? Are there any vendors looking at this?

Posted Nov 5, 2017, 9:00 AM UTC

1426
scrumplesplunge•

Certainly having string_view overloads would be good. I have personally found that string_view doesn't work well with legacy code expecting c-strings because it doesn't necessarily have a null terminator. This is the one case I'm aware of where const string& can't be replaced with string_view in a function parameter.

12
Xaxxon•

I wrote a zstring_view that is only constructible from either a char* or std::string for just this purpose. It lets me call functions with either a std::string or a char* (without constructing a std::string from it).. and it has a c_str() member function.

I pretty much exclusively use it for input parameters for functions. It also works for suffixes of things that are NUL terminated..

5
IAmBJ•

zstring_view is also in the GSL.

https://github.com/Microsoft/GSL

8
Xaxxon•

good to know, thanks!

2
BillyONealMSVC STL Dev•

Difficulties with P0506:

  1. that it is an ABI break
  2. several of the functions it changes, e.g. locale::locale(const char*), ultimately have to be passed as null terminated strings to underlying operating system (C) APIs in most implementations, meaning changing those to string_view makes a currently non-allocating API allocating.

I could see adding overloads to things but removal is going to be a tough sell.

10
nikbackm•

changing those to string_view makes a currently non-allocating API allocating

I thought (one of) the point(s) of string_view was to avoid unneeded allocations.

Why would it be needed in this case?

3
F54280•

Because the underlying OS API expect a NUL-terminated string, which has to be allocated by someone and get init'ed with the content of the string_view, followed by a NUL char.

3
SeanMiddleditchGame Developer•

Just about all of those functions only work with inputs of a given size (e.g. PATH_MAX) and a stack buffer can be used. Even for functions that take arbitrarily-long input, in most cases real-world inputs won't be so long, and the allocation can be conditional on the input length being over some "reasonable" size. And then most of those OS calls are IO routines where the time of allocation is essentially irrelevant compared to the time of the kernel call and IO operations themselves.

All that said, using overloads that add string_view support, none of this is a real problem. That also avoids the ABI issue someone else mentioned.

1
BillyONealMSVC STL Dev•

I don't know of a single API call we make that takes a string length for an input parameter except WideCharToMultiByte/MultiByteToWideChar. CreateFile wants null terminated strings. All the locale things want null terminated strings. Etc.

5
dodheimildjarn on SO and MSDN•

If you need null-termination and your string_view isn't explicitly null-padded then you must allocate a string in order to get said termination. Whereas if you had a string to begin with, it's guaranteed to always be null-terminated internally...

2
14nedBoost GSoC admin | AFIO & Outcome author•

There has been a fair bit of discussion of this on std-proposals, see https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/I4yTB54CctE

I'll reiterate my point made there here: if AFIO is accepted in 2018 as the File I/O TS, then its path_view design is of likely interest to this design decision too. Unlike string_view, it requires the character after the end to be readable. This lets us optimise out copying the string into a zero terminated buffer on POSIX where possible. As these can be up to 32Kb long, that's a fair saving.

Such requirements are too strong for non-path string views however. afio::path_view can get away with it only because one would hope it would be rare that people be placing filesystem paths in places where reading a character off the end is UB.

4
Z01dbrg•

it requires the character after the end to be readable

so passing "C:\a\b\0" instead of "C:\a\b" is UB assuming "C:\a\b\0" is the full original string?

(btw my strings are properly escaped, reddit eats double backslash)

Seems kind of error prone..., but maybe it is not. IDK since I never work with C strings.

1
14nedBoost GSoC admin | AFIO & Outcome author•

Not exactly. If you pass a subset of a zero terminated string, it will copy the subset into a temporary buffer, zero terminate it, and hand it to the OS. If on POSIX, as on Windows you don't need to zero terminate path strings, just tell it the length.

If the path view is already zero terminated, it gets used directly, no buffer copying.

1
Z01dbrg•

ah ok, idk it has that check for termination, I assumed it relies on programmer discipline. :)

In my defense something_view for me means no copy :)

1
14nedBoost GSoC admin | AFIO & Outcome author•

You might think it means that, but *_view often also means "hidden copy". On POSIX, almost all syscalls only accept zero terminated char arrays. If the C++ standard blindly replaces const char * with string_view, it forces implementations to always copy the string to an internal buffer - which may even be allocated via malloc - in order to ensure zero termination. And that would be stupid, so we best not do that (and we won't).

2
also_stl•

I understand the benefits of doing this, but having tested making the same change within my codebase, the overhead of passing a string_view (pointer+size) over a const std::string& (just a pointer) was unacceptable for my use case. The paper suggests changes which take string_view by value, by and large.

In one case, the increase in code size due to this change caused a function to no longer be inlined, which was really, really bad.

I don't see any mention of performance in the paper, so this concerns me. There are performance wins to be had here, but potential losses too.

3
kalmoc•

Well, I'm pretty sure that in a lot of places in the standard library (but certainly not all) where you'd use std::string_view, the performance of that doesn't really matter. E.g. if I'm opening a file, the overhead is really negligible.

The fact that it has to potentially copy &allocate a string however, because it has to be null terminated is imho the bigger problem.

4
Z01dbrg•

In one case, the increase in code size due to this change caused a function to no longer be inlined, which was really, really bad.

This is just not a proper complaint.

If you use PGO function will be inlined if it is hot. If you do not use PGO you do not care about performance.

0
also_stl•

Rubbish. PGO isn't a panacea because different code paths hit due to different data sets can cause conflicting decisions to be made. Plenty of people care about performance but find PGO to be impractical for their application. It takes great effort and care to ensure that your profile data set is "realistic" and this may not even be possible. A feature should never be designed to rely on the decisions it may make (and then may decide not to make, in the next release of your compiler).

2