Below are two common issues resulting in undefined behavior due to the sequence point rules:
a[i] = i++; //has a read and write between sequence points
i = i++;
A variation of Dario's example is this:
void Foo(shared_ptr a, shared_ptr b){ ... }
int main() {
Foo(shared_ptr(new Bar), shared_ptr(new Bar));
}
which might leak memory. There is no sequence point between the evaluation of the two parameters, so not only may the second argument be evaluated before the first, but both Bar objects may also be created before any of the shared_ptr
's
That is, instead of being evaluated as
Bar* b0 = new Bar();
arg0 = shared_ptr(b0);
Bar* b1 = new Bar();
arg1 = shared_ptr(b1);
Foo(arg0, arg1);
(which would be safe, because if b0
gets successfully allocated, it gets immediately wrapped in a shared_ptr
), it may be evaluated as:
Bar* b0 = new Bar();
Bar* b1 = new Bar();
arg0 = shared_ptr(b0);
arg1 = shared_ptr(b1);
Foo(arg0, arg1);
which means that if b0
gets allocated successfully, and b1
throws an exception, then b0
will never be deleted.