Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undefined behavior with std::move

Tags:

c++

c++11

From the move page of the cppreference

Unless otherwise specified, all standard library objects that have been moved from are placed in a valid but unspecified state. That is, only the functions without preconditions, such as the assignment operator, can be safely used on the object after it was moved from

So, from the example on the same page, this code below is considered undefined behaviour

vector<string> v_string;
string example = "example";
v_string.push_back(move(example));
cout << example << endl;

MSVC will output nothing on the console, but if I do this

vector<int> v_int;
int number = 10;
v_int.push_back(move(number));
cout << number << endl;

will output 10. Is there a reason why this happens? Or is it always undefined behavior?

like image 609
Astinog Avatar asked Sep 02 '15 06:09

Astinog


People also ask

What does std :: move () do?

std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.

What does move () do in C ++?

Move Constructor And Semantics: std::move() is a function used to convert an lvalue reference into the rvalue reference. Used to move the resources from a source object i.e. for efficient transfer of resources from one object to another.

Does STD move invalidate pointers?

Does std::move invalidate pointers? No. An object still exists after being moved from, so any pointers to that object are still valid.

Is std :: move necessary?

A: You should use std::move if you want to call functions that support move semantics with an argument which is not an rvalue (temporary expression).


1 Answers

Unspecified does not mean undefined.

According to the C++11 standard, section 17.3.26:

valid but unspecified state an object state that is not specified except that the object’s invariants are met and operations on the object behave as specified for its type

As the object is in a valid state, you can stream it to an output, as streaming has no additional preconditions. However what is printed is unspecified, so it may just print nothing, or print that your father smells of elderberries. What you can not safely do is use a function with additional preconditions such as back() which additionally requires the string to be non-empty. Valid strings can be empty.

Containing the old value is a perfectly acceptable option for the unspecified but valid state. In case of fundamental types such as int a simple copy is just the most efficient way to perform a move.

It should also be noted that int is not a standard library object, but a fundamental type (as defined in section 3.9.1). Therefore your quote does not apply.

like image 100
Joe Avatar answered Sep 29 '22 12:09

Joe