I have a wrapper for std::vector
and I've implemented function that replaces a section within a vector with another vector. I've tried to put the assignment of an iterator directly in the if
condition and got unexpected results.
I'm using Visual Studio 2013 and with FAIL
defined I get Debug Assertion Failed! - vector iterators incompatible. Is it possible that the condition is being evaluated from right to left? I can't get over it.
This is a (poorly implemented) code that reproduces my problem - meant to replace 3rd and 4th elements of vec
with 1st and 2nd elements of vec_second
:
#include <iostream>
#include <vector>
#include <iterator>
using std::cout;
//#define FAIL
int main()
{
std::vector<int> vec = {1, 2, 3, 4, 5};
std::vector<int> vec_second = {6, 7};
auto it = vec.begin() + 2;
#ifndef FAIL
it = vec.erase(it, it + vec_second.size());
if(it == vec.end())
#else
if((it = vec.erase(it, it + vec_second.size())) == vec.end())
#endif
vec.reserve(vec.size() + vec_second.size());
vec.insert(it, vec_second.begin(), vec_second.end());
for(auto const& x : vec)
cout << x << " ";
}
But runs fine on Coliru's GCC.
if((it = vec.erase(it, it + vec_second.size())) == vec.end())
Since there is no sequence point between them, a compiler is free to call erase
and end
in either order. If end
gets called first, that iterator is immediately invalidated by erase
, leading to undefined behavior.
Your #ifndef FAIL
code is the safe way to do this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With