Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::vector::insert() stopped working when migrating from MSVC 2013 (C++11) to MSVC 2019 (C++17)

I currently am migrating a large code base from

  • Visual Studio 2013 (v120)
  • C++11

to

  • Visual Studio 2019 (v142)
  • C++17

and now, my tests fail in strange places - I get index out of bounds crashes and other strange changes in behavior. Upon digging I noticed that the following code:

#include <iostream>
#include <vector>

int main()
{
    std::vector<std::vector<int>> nestedVector;
    nestedVector.insert(nestedVector.begin(), {});
    std::cout << nestedVector.size() << " elements";
}

produces a one-element vector in VS2013 but an empty vector in VS2019.

Other ways of inserting

nestedVector.insert(nestedVector.begin(), std::vector<int>{});
nestedVector.insert(nestedVector.begin(), std::vector<int>());

work in both setups and properly add a new element. What is happening here?

like image 400
PhilLab Avatar asked Jul 13 '19 07:07

PhilLab


1 Answers

As was already mentioned in the comments, in your original program the call of nestedVector.insert(nestedVector.begin(), {}) selects the overloaded method:

iterator insert( const_iterator pos, std::initializer_list<T> ilist );

see https://en.cppreference.com/w/cpp/container/vector/insert.

Since the initializer list is empty, nothing is really inserted and the vector size is zero at the end. It is the same behavior in all compilers, demo: https://godbolt.org/z/9nnET5ren

Apparently, VS2013 did not implement this overload of insert method, so another one called:

iterator insert( const_iterator pos, const T& value );

creating one element in the vector. This is wrong behavior.

like image 185
Fedor Avatar answered Nov 12 '22 10:11

Fedor