0

Let us give any data structure containing objects of std::string_view:

std::vector<std::string_view> v{ "abc", "def" };
std::deque<std::string_view> d{ "abc", "def" };
std::set<std::string_view> s{ "abc", "def" };

Is it guaranteed by cpp standard, that these containers store objects of class std::string_view which point to the string literals ended with null?

I mean is it safe to write code like this:

void foo(const char* ptr) {
    printf("%s", ptr);
}

for (auto elem : v)
    foo(elem.data());

for (auto elem : d)
    foo(elem.data());

for (auto elem : s)
    foo(elem.data());
Michal
  • 35
  • 3
  • Have you at least tried it? It would add more "weight" to your question. Because you could then say "I tried this out, and it looks like it worked, but I am still unsure if it's correct and/or safe." That's a lot better than "Here's some code I couldn't be bothered to run myself. Is it ok?" – sweenish Nov 03 '21 at 15:17
  • 3
    Trying things out is not a good way to determine expected behavior or correctness of code in languages with a concept of "undefined behavior" like C++. @sweenish – Cody Gray - on strike Nov 03 '21 at 15:24
  • @CodyGray I feel that you didn't actually read my comment. – sweenish Nov 03 '21 at 15:25
  • @sweenish I didn't get the impression that OP didn't try running the code. To me, *"Is it guaranteed by cpp standard"* and *"is it safe"* imply that they tried and got the expected behavior. If they didn't try, they probably would've just asked "are those string_views null-terminated", without mentioning the standard. – HolyBlackCat Nov 03 '21 at 15:25
  • @HolyBlackCat And to me that's a large assumption that I don't feel comfortable making. – sweenish Nov 03 '21 at 15:27
  • What I'm saying is, it doesn't add any "weight" to the question at all, because it's entirely a waste of time and, if anything, likely to lead someone astray. The formulation of the question you proposed in your comment is *precisely* what I *don't* want to see a programmer doing or asking. @sweenish – Cody Gray - on strike Nov 03 '21 at 15:27
  • @CodyGray You don't want programmers learning by doing, and then asking whether the behavior they see is enforced? I see nothing wrong with that approach. – sweenish Nov 03 '21 at 15:28
  • 2
    No, I don't want C or C++ programmers learning by experimentation. That leads to buggy code and misunderstandings, which cause me no end of headaches. I would rather they consult the standard, a trusted reference material, or ask someone who knows. – Cody Gray - on strike Nov 03 '21 at 15:29
  • @CodyGray You keep excluding the part where they follow on with a question. Learning **only** by experimenting is less than ideal. I don't disagree with that. – sweenish Nov 03 '21 at 15:30
  • 1
    Yes, I'm missing what the point is of doing busy work to run an experiment that generates data that is meaningless because it cannot be generalized, if you're going to anyway follow it up by trying to find out for sure. What's the purpose of that? Honestly, this seems more like gate-keeping, as if you expect some minimum "effort" bar for questions on Stack Overflow. That's not the case on this site; we allow questions from beginning to advanced. Although it is generally expected that one do a search first to see if the topic's already been covered. – Cody Gray - on strike Nov 03 '21 at 15:31
  • @CodyGray Gate-keeping? No. Minimum effort bar? Yes. As outlined in [ask], [mre], and the many other resources that are constantly posted to people who don't clear that bar. Beginner level and advanced questions are all expected to cross that threshold. – sweenish Nov 03 '21 at 15:33
  • I see literally nothing wrong with blending the academic and learn-by-doing approach. Right now it sounds like you want front-load people with a ton of information before they even get to helloworld.cpp. What's so egregious about trying something, and then wondering if the behavior you observed is enforced or not? – sweenish Nov 03 '21 at 15:35
  • 1
    "Minimal reproducible example" is for debugging questions. This isn't one. There's no threshold for beginner questions, other than that they are [on-topic](https://stackoverflow.com/help/on-topic); namely, that they are about a practical programming topic, reasonably scoped such that they can be answered in our Q&A format, not primarily based on opinions, nor soliciting recommendations of off-site resources. "How to Ask" is, of course, always relevant and recommended. It doesn't say that you have to try the code yourself, or set any sort of minimum effort bar, aside from a coherent question. – Cody Gray - on strike Nov 03 '21 at 15:35
  • And yet "do my homework" questions are constantly shut down. Maybe we've been wrong the whole time? They are on-topic, since they're about a specific programming problem. They're always scoped reasonably since the assignments are trivial. They are not opinion-based, nor do they ask for opinions or external resources. – sweenish Nov 03 '21 at 15:38
  • 1
    Yes, closing questions just because they're homework is incorrect. However, assignment dumps are not questions, so, yes, those should obviously be closed as "unclear". – Cody Gray - on strike Nov 03 '21 at 15:39
  • They're not unclear. The requirements are usually laid out very clearly. – sweenish Nov 03 '21 at 15:40
  • Learning coding by coding is not a bad thing. Yes, they'll make mistakes. Yes, they'll employ bad practices at times. But if they are then coming here to ask questions, they'll get corrected, and continue to write code. I mean, do you realize what we're quibbling over? 2 minutes of effort, if that. "Here's a short program I compiled and ran. It looks like correct behavior, but is it correct according to the standard?" Look at all the trauma and gate-keeping I've inflicted. – sweenish Nov 03 '21 at 15:43

1 Answers1

2

Yes, this is safe.

In general std::string_views don't have to be null-terminated, but here you explicitly initialized them with null-terminated strings.

The compiler is not allowed to remove null-terminator from a string based solely on the fact that it's assigned to a string_view.

The only case when it would be allowed to do so is if it didn't change the program behavior (the as-if rule), meaning you don't need to worry about it.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • Am I correct that that would not generally work if you constructed a string_view from a std::string? – SirGuy Nov 03 '21 at 15:25
  • @SirGuy `std::string` itself is null-terminated, so that's safe too. OTOH, you're allowed to construct `string_view` from a **part** of a `string`, then there will be no null-terminator. – HolyBlackCat Nov 03 '21 at 15:28
  • 1
    @SirGuy It depends if you include the end of the string or not. If you dont and try to pass the string view's data as a `char*` it will ignore where the `string_view` would normally end and actually end where the later null terminator is. – François Andrieux Nov 03 '21 at 15:29
  • @HolyBlackCat According to [this](https://stackoverflow.com/a/11752711/1277769) std::string is not guaranteed to include a null terminator, however the return value of std::string::c_str does. How an implementation achieves that could mean that the null-terminator is always present, but relying on that would not be "guaranteed by the standard" – SirGuy Nov 03 '21 at 15:32
  • 3
    @SirGuy When converting `std::string` to `std::string_view`, `std::string_view` is constructed from `std::string::data()`, which is guaranteed to be null-terminated (since C++11), then it'll be fine as long as the `std::string`'s lifetime is long enough. – songyuanyao Nov 03 '21 at 15:44