最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - C++17: Guaranteed Copy elision not working - Stack Overflow

programmeradmin4浏览0评论

I have written the below code...

#include <iostream>
using namespace std;

struct Error {
   Error() { cout << "Constructor called\n"; }
   Error(const Error&) { cout << "Copy Constructor called\n"; }
};
void test() {
   throw Error();
}
int main() {
   try {
      test();
   }
   catch (Error e) {
   }
}

I am getting the following output on C++17 and later...

Constructor called
Copy Constructor called

Even the C++17 Guaranteed copy elision says "Copy elision is mandatory in Throwing and catching exceptions by value". I am getting the "Copy Constructor called" as output.

Am I missing something?

I have written the below code...

#include <iostream>
using namespace std;

struct Error {
   Error() { cout << "Constructor called\n"; }
   Error(const Error&) { cout << "Copy Constructor called\n"; }
};
void test() {
   throw Error();
}
int main() {
   try {
      test();
   }
   catch (Error e) {
   }
}

I am getting the following output on C++17 and later...

Constructor called
Copy Constructor called

Even the C++17 Guaranteed copy elision says "Copy elision is mandatory in Throwing and catching exceptions by value". I am getting the "Copy Constructor called" as output.

Am I missing something?

Share Improve this question edited yesterday NJMR asked yesterday NJMRNJMR 1,9641 gold badge28 silver badges50 bronze badges 4
  • 1 C++17 Guaranteed copy elision says Can you add a reference to that? BTW I can't reproduce the output, I am getting error: use of undeclared identifier 'cout'. – 3CxEZiVlQ Commented yesterday
  • It's only the draft standard, but I don't see that it provides any such guarantees for the handler eel.is/c++draft/class.copy.elision#1.4. – frippe Commented yesterday
  • iirc the rul about try\catch block didn't change since C++11. – Swift - Friday Pie Commented yesterday
  • There is a reason that the guidelines say catch errors by const& : E.15: Throw by value, catch exceptions from a hierarchy by reference – Pepijn Kramer Commented 23 hours ago
Add a comment  | 

1 Answer 1

Reset to default 7

Copy elision is mandatory in Throwing and catching exceptions by value

Honestly, this is not mandatory, see below, and this works as expected - when test() is called, a compiler reserves a memory where Error will be constructed if test() throws an exception. Until C++17, it could create Error and copy it to that reserved storage.

The copy, that you observe, is done here: catch (Error e) - Error is copied from that reserved storage to a function local argument. Until C++17, the output could be

Constructor called
Copy Constructor called
Copy Constructor called

If you don't want to copy an object, fix it: catch (Error &e) or catch (const Error &e).

#include <iostream>

struct Error {
  Error() { std::cout << "Constructor called\n"; }
  Error(const Error &) { std::cout << "Copy Constructor called\n"; }
};

void test() { throw Error(); }

int main() {
  try {
    test();
  } catch (const Error &e) {
  }
}

// Output since C++17:
// Constructor called
// 
// Possible output until C++17:
// Constructor called
// Copy Constructor called

class.copy.elision#1.4

the copy-initialization of o can be omitted by treating the exception-declaration as an alias

The standard is saying that catch (Error e) can be treated as catch (Error &e). Note, can is not must.

发布评论

评论列表(0)

  1. 暂无评论