0

Is noexcept good in the code below ? according to cppreference the string move constructor never throw exception and if i undrestant well rvalue + lvalue = rvalue

void foo(const std::string& p_str) noexcept{
   std::string l_str {p_str + "FOO"};
}
  • 4
    Probably not, string can do dynamic memory allocation so you could in theory expect std::bad_alloc. (p_str + "FOO" will not only be a move constructor call, but will create a new temporary std::string) – Pepijn Kramer Aug 22 '22 at 11:22
  • that is the case of other constructors not the move one i think – casaDePapel Aug 22 '22 at 11:28
  • @casaDePapel It is, indeed, though in the context of the question (*'is noexcept good **in the code below**'*) the answer still remains *'no'*... – Aconcagua Aug 22 '22 at 11:31
  • @Aconcagua my static code analyser : Polyspace is not agree, it doen't accept noexcept here! maybe bugg on it ? – casaDePapel Aug 22 '22 at 11:37
  • 1
    It does *not* accept `noexcept`? But that's what we're saying, too: *'It is **not** good'*. The move constructor doesn't throw, indeed, but `operator+` creates a totally new `std::string` (as Pepijn explained already) – a temporary – and *that one* might throw on construction. What is passed to the move constructor is *not* p_str, but this temporary instead. If an exception is thrown, then even *before* the move constructor gets called. – Aconcagua Aug 22 '22 at 11:42
  • 2
    "https://en.cppreference.com/w/cpp/string/basic_string/operator%2B" Is NOT noexcept, so your analyser is correct – Pepijn Kramer Aug 22 '22 at 11:42
  • 1
    Actually the move constructor should not get called at all here (but still is required to exist!) due to copy elision/return value optimisation... – Aconcagua Aug 22 '22 at 11:45
  • @Aconcagua, @Pepijn Kramer you are right, thank you, the pb is with the ``` operator+ ``` – casaDePapel Aug 22 '22 at 11:47
  • @Aconcagua you mean that rvalue + lvalue = rvalue is not good ? – casaDePapel Aug 22 '22 at 11:50
  • `noexcept` in this piece of code is not good. That's what the entire question is about, isn't it? `noexcept` is mentioned in the sentence right before, isn't it? You seem to deliberately misinterpret my comments :( – Aconcagua Aug 22 '22 at 11:56
  • @Aconcagua (sorry), ok for noexcept i undrestant. it was just about this: (the move constructor should not get called at all here) – casaDePapel Aug 22 '22 at 12:07
  • `noexcept` means you intend for the function you've designed to not throw exceptions. As far as I'm concerned, If I had a function to add strings together, I would not be expecting it to throw an error, and should my code reach a point where it does, for instance if it can no longer allocate memory, you're very much screwed. [see more on bad_alloc, I approve highly of the first answer](https://stackoverflow.com/questions/9456728/how-to-deal-with-bad-alloc-in-c). in short, just because you call functions where it may throw, doesn't mean you have to making it's callers `noexcept(false)` – Salih MSA Aug 22 '22 at 12:36
  • @Salih MSA noexcept(false) is equivalent to not qualify function i think but for static code analyser is better to put noexpect(false) – casaDePapel Aug 22 '22 at 12:43
  • @casaDePapel I agree. It also has the benefit in that all code I write, especially when I know the code will need to be ran and possibly modified by others, it's yet another way of clearly demonstrating intentions. – Salih MSA Aug 22 '22 at 12:46
  • @casaDePapel Never mind... OK, then is this new context: `any value + any value = rvalue` – this remains true. However due to return value optimisation and copy elision we can expect that in the final compiled code the string resulting from the call to `operator+` will be constructed *directly* at `l_str`, ommitting the temporary entirely and thus the need for calling the move constructor. – Aconcagua Aug 22 '22 at 14:10

0 Answers0