Consider the following code:
void Log(std::string_view msg,
std::source_location const& loc = std::source_location::current()) {
// Performance penalty!
auto const n = std::strlen(loc.file_name());
auto s = ""s;
s.resize(msg.size() + n);
std::memcpy(&s[0], msg.data(), msg.size());
std::memcpy(&s[msg.size()], loc.file_name(), n);
// sendToRemoteMachine(s);
}
Obviously, if std::source_location::file_name returns a std::string_view, the performance penalty can be easily avoided.
I think, std::source_location::file_name is a compile-time generated and readonly information. The compiler can store it into an std::string_view object.
Why doesn't std::source_location provide lengths to avoid performance penalty in C++20?
Update
Another related article: std::source_location is Broken
C++ does not have a type that represents all of the following:
std::stringhas both 2 and 3, but not 1.string_viewhas 1 and 2, but does not guarantee 3 at the type level.char const*has 1 and there's a general expectation that they use 3, but they don't carry 2.And yes, #3 is actually quite important. Your example wants to pass the string to an API that needs a sized string; that's why you're computing the size. Other people will have APIs that expect an NTBS. For them, a
string_view-based API now requires that they copy the sized-string into an NTBS. Which is an O(N) operation.Unless you have a type that communicates all 3 of these, one of you is going to have to do an O(N) operation.
Yes, technically, a
string_viewcould point to an NTBS. But at the type level, if you're handed astring_view, you don't know that it points to an NTBS. That would be a guarantee from the function that generates it, not from the type itself. So it would be an inappropriate use of the type.This article is about a largely separate issue: the lack of a
constexprversion ofsource_location, one which would allow the string to be guaranteed to only exist at compile-time.This issue is not something that any library construct could ever solve. Returning
string_viewfrom member functions wouldn't fix the problem from that article. Whilestring_viewcan beconstexpr, parameters cannot. And sincesource_locationis passed as a parameter, it must follow the rules of the C++ language. Even though the compiler generated it, it is a parameter of the function and therefore it cannot be aconstexprparameter.Indeed, it couldn't even be a C++ language construct because the language cannot pass compile-time information as a function parameter. Remember: the source of the information is the caller. What the writer of that article would do with
__FILE__is manually stick it into a template parameter of that function, not a function parameter.And it should be noted: returning a size isn't the problem as outlined by the article. You can compute a size of a
char const*at compile-time, if thechar const*itself isconstexpr. You can then use that compile-time size and thechar const*itself to manufacture a type. The problem the article is talking about is entirely in the scope of getting a compile-time sequence of characters. Whether it's astring_viewor achar const*NTBS or achar[N]is irrelevant; any of them would work.