https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83982

            Bug ID: 83982
           Summary: Exception guarantee of C++14 vector::resize(size_type)
                    is not met
           Product: gcc
           Version: 7.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dtrebbien at gmail dot com
  Target Milestone: ---

In [vector.capacity], C++14 mentions for `void resize(size_type sz)':

"Remarks: If an exception is thrown other than by the move constructor of a
non-CopyInsertable T there are no effects."


Testing g++ 7.2.0, I have found that if an exception is raised by the default
constructor, then there might be effects.

Here is a test case:


#include <cassert>
#include <iostream>
#include <stdexcept>
#include <vector>

struct T {
  static int s_count;

  T()
    : m_num(s_count++)
  {
    if (s_count > 1) {
      throw std::runtime_error("too many");
    }
  }

  T(T&& other)
    : m_num(other.m_num)
  {
    other.m_num = -1;
  }

  int m_num;
};

int T::s_count = 0;

int main() {
  std::vector<T> a(1);
  std::cout << "a[0].m_num before = " << a[0].m_num << '\n';
  assert(a[0].m_num == 0);
  try {
    a.resize(2);
  } catch (...) {
    // ignore
  }
  std::cout << "a[0].m_num after = " << a[0].m_num << '\n';
  assert(a[0].m_num == 0);

  return 0;
}


I expect that a[0].m_num will be unchanged by the failed resize() call;
however, it changes to -1.

Reply via email to