0

In C++ Extensions for Library Fundamentals, Version 2, it is stated that, for string_view constructor:

constexpr basic_string_view(const charT* str, size_type len);

Requires: [str,str + len) is a valid range.

But it is not defined what a “valid range” is. Is it undefined behavior if a string_view is constructed with a pointer to non-owned memory?

Also, is it required that a string_view always point to owned memory for its entire lifetime, or does it apply only to constructor?

If so, what is the rationale for this decision?

Craig M. Brandenburg
  • 3,354
  • 5
  • 25
  • 37
Serdar Sanli
  • 1,064
  • 1
  • 11
  • 20
  • What is *a pointer to non owned memory*? Are you talking a pointer like `nullptr`? – NathanOliver Mar 09 '17 at 20:38
  • From the wording it looks like if len is 0, the statement is vacuous (always true). So if you make len 0, you can pass any pointer you want. Otherwise, valid range would need to be something that your program can read as a string. It definitely needs to be owned by your process, otherwise that would be UB. – Nir Friedman Mar 09 '17 at 20:41
  • "Complexity: O(traits::length(str))" suggests that it the standards body is leaving the implementor's options open. An implementation may be looking at whatever's being pointed at, so it better be safe. – user4581301 Mar 09 '17 at 20:41
  • Please note that this is the constructor that that takes the length as a parameter, so constructor should be O(1) and not need to scan the string. – Serdar Sanli Mar 09 '17 at 20:44
  • Right, not need to scan, but like I said the option looks like it's being left open to the implementor. They could scan without violating the standard. No one needs to scan or from the looks of it, needs to copy the string, so I'd keep the source string around at least as long as the view. – user4581301 Mar 09 '17 at 20:49
  • [Here](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#string.view) it is stated: `The complexity of basic_string_view member functions is O(1) unless otherwise specified. ` – Serdar Sanli Mar 09 '17 at 20:52
  • I retract. I was looking at the wrong constructor (`constexpr basic_string_view(const charT* str);`). For the null-terminated string, of course it needs to scan. For the length-based constructor there is no need. – user4581301 Mar 09 '17 at 20:52
  • 1
    @MustafaSerdarŞanlı I'm not really sure ultimately what you are getting at. It is quite possible that if the only thing you do with string view is construct it and destruct it, and nothing else, you may not trigger UB. But that is implementation dependent. You are not meeting the preconditions of the class if you pass a pointer to un owned memory and positive length, so you can't "expect" anything (not even clean destruction). – Nir Friedman Mar 09 '17 at 20:53
  • @NirFriedman I want a parser to populate vector of `std::string_views`, and have a single `std::string` to hold all parsed string data. One option is to append "foo\0" to the `std::string` and point next `std::string_view` to it. But since appending to string might cause string to be reallocated, the string view would point to invalid memory. Instead, I could temporarily store (idx, len) in the string_view and at the end of parsing make them string_view(str.data() + idx, len). I know I can store it somewhere else, but I'd rather not, if it is not an undefined behavior this way. – Serdar Sanli Mar 09 '17 at 21:03
  • And more importantly, standard is unclear on this, so it is not only my issue here. – Serdar Sanli Mar 09 '17 at 21:05
  • 1
    "valid range" is defined in the c++ standard in `[iterator.requirements.general]` iirc. That definition would preclude using a non-address with a non-zero length. I think that two null pointers are a valid range, but that wouldn't help you. For [i, j) to be a valid range, j must be reachable from i with a finite number of applications of the `++` operator; that operator has UB if its argument is not a valid iterator. – rici Mar 09 '17 at 22:42

0 Answers0