This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/78805] New: std::vector<T>::emplace_back is not exception safe.
- From: "lanxingcan at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 14 Dec 2016 09:55:02 +0000
- Subject: [Bug libstdc++/78805] New: std::vector<T>::emplace_back is not exception safe.
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78805
Bug ID: 78805
Summary: std::vector<T>::emplace_back is not exception safe.
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: lanxingcan at gmail dot com
Target Milestone: ---
Consider the following code
```cpp
#include <vector>
#include <iostream>
#include <stdexcept>
class A
{
public:
int id;
A(int x, bool throws = false)
: id(x)
{
if (throws) throw std::runtime_error("bang!");
}
};
int main()
{
std::vector<A> b;
b.reserve(4);
b.emplace_back(1);
b.emplace_back(2);
b.emplace_back(3);
try
{
b.emplace(begin(b) + 2, 4, true);
}
catch(...)
{
}
for (auto &x : b)
{
std::cout << x.id << std::endl;
}
}
```
This code is expected to print
1
2
3
but prints
1
2
3
3
instead.
The reason is that an exception is thrown when emplacing the fourth element to
the vector, while at the time the 3rd element has already been copied to next
place.
This is obviously a exception-safety issue. I didn't check the ISO standard but
[cppreference] states that this function should provide strong exception
guarantee.
Both MSVC and clang(libc++) works as expected.
[cppreference]: http://en.cppreference.com/w/cpp/container/vector/emplace
** This bug was originally discussed at https://zhuanlan.zhihu.com/p/24365844
**