SlideShare a Scribd company logo
Andrey Upadyshev
Hot C++:

Rvalue References And
Move Semantics
Licensed under a CC BY-SA 4.0 License. Version of 2019.04.30
!1
Overview
❖ Rvalue references
❖ Move semantics
❖ It’s well assisted!
❖ More ways to shoot yourself in the foot
!2
Rvalue References
!3
Lvalue And Rvalue (how came from C)
• lvalue - may appear on the left hand side of an
assignment, represents storage region locator value, i.e.
evaluates to object identity.
• All the rest is non-lvalue or rvalue (because can appear
on the right hand side of assignment only)
!4
Lvalue And Rvalue, Example 1
int a = 42; // OK lvalue on left side of assignment
int b = 43; // and rvalue on right side
a = b; // OK, lvalue may be on any side of assignment
b = a; // OK, lvalue may be on any side of assignment
int c = a * b; // OK, rvalue on right side of assignment
a * b = 42; // err, rvalue on left hand side of assignment
int *p = &i; // OK, i is an lvalue
int *p1 = &43; // err, cannot take the address of an rvalue
!5
Value Categories (C++11)
• lvalue - is an expression that identifies a non-temporary
object
• prvalue ("pure" rvalue) - is an expression that identifies a
temporary object or is a value not associated with any
object (C++03 rvalue)
• Ex: The result of calling a function whose return type is
a value
• xvalue (an “eXpiring” value) - is an expression that
identifies expiring object, that is, the object that may be
moved from
• Ex: The result of calling a function whose return type is
an rvalue reference
!6
Simplified!
}rvalues
std::cout << &bar().member; // ?
Lvalue And Rvalue, Example 2
Foo& foo(); // `foo()` is lvalue

foo() = 42; // OK

std::cout << &foo(); // OK
Bar bar(); // `bar()` is prvalue

Bar && pub(); // `pub()` is xvalue

Bar b2 = bar(); // OK

bar() = b2; // cannot assign to an rvalue

std::cout << &bar(); // cannot take the address of an rvalue

std::cout << &pub(); // …
!7
std::cout << &bar().member; // reference to a member of an rvalue

// is an rvalue!
Lvalue References
void foo(const Bar& bar); //[1]

Binds to lvalue and rvalue. Can not modify bar.
void foo(Bar& bar); //[2]

Binds to lvalue only. Can modify bar. (Very old Visual C++ versions
bind it to rvalue too. But this does not conform to the Standard)
!8
Bar read_bar(const char *filename);
foo(read_bar(“bar.txt”)); ?
foo(read_bar(“bar.txt”)); // [1] => bar is const
Rvalue References
!9
void foo(const Bar& bar); //[1]
Binds to lvalue and rvalue. Can not modify bar.
void foo(Bar& bar); //[2]
Binds to lvalue only. Can modify bar.
void foo(Bar && bar); //[3]
Binds to rvalue only. Takes precedence over lvalue overloads. Can
modify bar.
void foo(const Bar && bar); //[4]
Binds to rvalue only. Takes precedence over lvalue overloads. Can not
modify bar. [Almost] has no useful meaning. Use const ref overload
instead.
foo(read_bar(“bar.txt”)); // [3] => bar is mutable!
Why Do I Need Them At All?
void foo(Bar && rv);
❖ In short: to use move semantics!
❖ Longer:
❖ Because rvalue references bind to rvalue, they can be
used to extend the lifetime of a modifiable temporary
(an rvalue is a temporary, remember?).
❖ You can do funny things with temporary, e.g. safely
steal any data you need from it (nobody cares, heh).
It’s called move semantics.
!10
Move Semantics
!11
Move Semantics In Example
Copying
MemBuf lv = rv;
class MemBuf { void *m_data; size_t m_size; ... };
!12
F1 23 4C DB 98 73 11 ...
rv
allocate
and copy
F1 23 4C DB 98 73 11 ...
lv contains a copy of rv's
content
lv
Moving
MemBuf lv = std::move(rv);
F1 23 4C DB 98 73 11 ...
rv
lv
lv grabs (steals) content of rv
rv in moved-from state
X
Moved-From Objects
❖ Moving-from does not abolish destructing. The object’s destructor
is be called anyway!
❖ Moved-from object should be placed in a valid but unspecified
state, so it is safe to:
❖ destroy it
❖ assign one a new value (is assignable)
❖ A type may provide more strong guaranty. E.g. there is guaranty
that moved-from STD smart pointers are empty.
!13
F1 23 4C DB 98 73 11 ...
rv
lv
X
Why Move Semantics?
The best possible performance for classes with expensive copy while
keeping the clear interface.
❖ std::vector<HugeObject> performing bad in C++03:
❖ Copies elements on insertion and even more on growing.
❖ Can be passed around only wrapped with smart pointer.
❖ So we used std::vector<std::shared_ptr<HugeObject>> or
boost::ptr_vector<HugeObject> to gain performance but got new problems:
❖ Extra allocation and extra level of indirection (performance!)
❖ Extra complexity
❖ Doesn’t work smoothly with STL algorithms (OK, ptr_vector does)
❖ Thanks to move semantics std::vector<HugeObject> become good in C++11
(finally!):
❖ Elements are moved on insertion and on growing
❖ No [smart] pointer involved overhead
❖ Clear and simple, STL algorithms works perfect
❖ Can be moved around
!14
Why Move Semantics?
❖ Cleaner interface for non-copyable but movable objects (like files,
threads etc):
❖ std::auto_ptr<File> openFile(

const char *filename); // C++03
❖ File openFile(const char *filename); // C++11
!15
Adding Move Semantics To a Class
❖ There are two new special member functions:
❖ Move constructor:

Foo::Foo(Foo&& op);
❖ Move assignment operator:

Foo& operator= (Foo&& op);
❖ Like copy ctor/assignment operator, but moves from its argument.
❖ The functions are compiler generated by default (use it!) but may be user
provided, explicitly defaulted or deleted.
❖ Compiler uses similar rules as for copy ctor/copy assignment operator
generation.
❖ Visual Studio before 2015 does not generate move ctor/move
assignment. You must do it manually.
!16
Forcing Move Semantics
template<class T>

void swap_opt(T& a, T& b)

{

T tmp(a);

a = b;

b = tmp;

}
Hm, copying…
std::move just casts lvalue to rvalue (no moving itself!) what allows a move semantics
to be used. Scott Meyers said that perhaps one should be called rvalue_cast
!17
template<class T>

void swap_opt(T& a, T& b)

{ 

T tmp(std::move(a));

a = std::move(b);

b = std::move(tmp);

}
Moving!!!
Let’s implement optimized swap that utilize move semantics.
For simplicity, assume that it will be applied only to movable types.
Forcing move semantics leaves moved from objects behind, so must be uses carefully:
std::string tmp("bla-bla");

std::string s(std::move(tmp));

std::cout << tmp; // Using of 'moved from' object (e.g. by mistake) for

// other then assigning. Undefined behavior for most types
It’s Well Assisted
!18
Supported By STL
❖ C++11 STL is significantly extended to support rvalue references
and move semantics:
❖ All containers and other types storing user types (pair, tuple,
future, function, smart pointers etc) are move-aware.
❖ New algorithms: move, move_forward
❖ New iterator adapter: move_iterator
❖ Movable, non-copyable unique_ptr replaces flawy auto_ptr
(which is deprecated)
❖ Optimized swap for movable types
❖ New type traits
!19
Ref Qualifiers
❖ Member functions can be specified with ref-qualifier & or &&, placed
after cv-qualifier:
❖ const Foo& Bar::foo() const & { // [1]

return m_foo;

}
❖ Foo&& Bar::foo() && { // [2]

return std::move(m_foo); // `*this` is always

} // lvalue
❖ Allow to have different overloads for lvalue and rvalue (temporary).
❖ No ref-qualifier means “whatever” (for backward compatibility)
❖ A function with a ref-qualifier can not overload with a function without
one.
!20
Perfect Forwarding & Forwarding
References
❖ Perfect forwarding is finally possible!
❖ Thanks to forwarding (aka universal) references and new
reference collapsing rules:
❖ template<class P1, class P2>

void create_foo(P1 && p1, P2 && p2) {

Foo foo(std::forward<P1>(p1),

std::forward<P2>(p2));

…

}
❖ Looks even better with variadic templates (not a sarcasm!)
❖ It is a big topic for another talk
!21
Optimization
❖ Copy elision does elision of both copy and move
operations
❖ When copy elision is not applicable, compiler prefers
moving over copying.
!22
Special Member Functions
❖ Move constructor and move assignment operator aren’t generated if copy
constructor, copy assignment operator or destructor is explicitly declared.
❖ Copy constructor and copy assignment operator aren't generated if move
constructor or move assignment operator is explicitly declared
❖ Not supported before Visual Studio 2015
❖ Rule of three become rule of five:

If a class defines one of the following it should probably explicitly define all five:
•destructor
•copy constructor
•copy assignment operator
•move constructor
•move assignment operator
!23
More Ways To Shoot Yourself In
The Foot
!24
Named Rvalue Reference Is Not an Rvalue
Foo::Foo(Bar && bar)

: m_bar(bar) {} //[1] Is something wrong?
Named rvalue reference identifies an object => it is lvalue.

i.e. bar is copied unless move semantics is forced
Foo::Foo(Bar && bar)

: m_bar(std::move(bar)) {} //[2] OK
Foo::Foo(Foo && rh)

: m_bar(rh.m_bar) {} //[3] copy, ref to lvalue member is an lvalue
Foo::Foo(Foo && rh)

: m_bar(std::move(rh.m_bar)) {} //[4] OK

// or even safer

: m_bar(std::move(rh).m_bar) {} //[5] OK, ref to rvalue member is

// rvalue
!25
Returning of Rvalue Reference
Foo && make_foo() { //[1] Is something wrong?

return Foo(42);

}
An rvalue reference is a reference. Returning a reference to a
local object is bad. Return by value instead
Foo make_foo() { //[2] OK

return Foo(42);

}
Return rvalue reference only when you really know that you need this. A right
example is std::move:
template<class T>

typename std::remove_reference<T>::type&& std::move(T && t) {

return static_cast<typename std::remove_reference<T>::type &&>(t);

}
!26
❖ Applying std::move to a const object does
not activate move semantics! You quietly got
copy instead of move.
❖ const Foo f = make_foo();

return Bar(std::move(f));

// Moving of `f` is blocked
❖ std::move does not remove object constness
❖ No compilation error generated in such case.
❖ Confusing unjustified behavior. One can write
something like safe_move to protect himself.
std::move And Const Objects
!27
Move Semantics and RVO
!28
struct Foo {…};
Foo make_foo1() {

Foo r(…);

return std::move(r);

}
Everything correct?
RVO is blocked, r is moved or copied
Foo make_foo1() {

Foo r(…);

return r;

}
RVO is applied, no move or copy
Move Semantics and RVO
!29
struct Bar {…};
struct Foo {

Foo(const Bar& rh);

Foo(Bar && rh);

…

};
Foo make_foo2() {
Bar bar(…);
return bar;

}
Everything correct?
Actually it is `return Foo(bar)`. bar is copied
Foo make_foo2() {
Bar bar(…);
return std::move(bar);

}
Actually it is `return Foo(std::move(bar))`. bar is moved. We can’t get any better here
Move Semantics And Exception Safety
❖ // Huge object

struct Elephant {

Elephant(const Elephant& op);

Elephant(Elephant && op);

Elephant& operator= (const Elephant& op);

Elephant& operator= (Elephant && op);

…

};



std::vector<Elephant> all_elephants;

… // Heavily use it
❖ Does everything look good?
!30
Move Semantics And Exception Safety
For good reason STL containers may copy elements internally unless
ones' move constructor doesn't throw. Special traits are used:
std::move_if_noexcept
std::is_nothrow_move_constructible
To get rid of copy, add noexcept to the move special functions (only
if function really doesn't throw, no cheating, please!):
Elephant(Elephant && op) noexcept;
Note that noexcept is not supported in Visual Studio before 2015, use
macro like BOOST_NOEXCEPT (<boost/config/suffix.hpp>):
Elephant(Elephant && op) BOOST_NOEXCEPT;
!31
Useful Links
Alex Allain, Move semantics and rvalue references in C++11

http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html
Dave Abrahams, Exceptionally Moving!

http://web.archive.org/web/20130524084627/http://cpp-next.com/archive/2009/10/exceptionally-moving/
Stephan T. Lavavej, Don’t Help the Compiler

http://channel9.msdn.com/Events/GoingNative/2013/Don-t-Help-the-Compiler
Andrzej Krzemieński, Ref-qualifiers

https://akrzemi1.wordpress.com/2014/06/02/ref-qualifiers/
Max Galkin. C++ curiosities: one does not simply move a const object

http://yacoder.net/blog/2015/05/06/cpp-curiosities-one-does-not-simply-move-a-const-object/
C++ Reference

http://en.cppreference.com/w/
Value categories

https://en.cppreference.com/w/cpp/language/value_category
C++11 Standard (final plus minor editorial changes)
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
!32
Questions?
!33
I HAVE NO IDEA

WHAT’S GOING ON.

More Related Content

What's hot

What is Switch Case?
What is Switch Case?What is Switch Case?
What is Switch Case?
AnuragSrivastava272
 
Virtual function in C++ Pure Virtual Function
Virtual function in C++ Pure Virtual Function Virtual function in C++ Pure Virtual Function
Virtual function in C++ Pure Virtual Function
Kamlesh Makvana
 
Type Conversion, Precedence and Associativity
Type Conversion, Precedence and AssociativityType Conversion, Precedence and Associativity
Type Conversion, Precedence and Associativity
Aakash Singh
 
Advanced Programming C++
Advanced Programming C++Advanced Programming C++
Advanced Programming C++
guestf0562b
 
C++20 features
C++20 features C++20 features
C++20 features
LogeekNightUkraine
 
If-else and switch-case
If-else and switch-caseIf-else and switch-case
If-else and switch-case
Manash Kumar Mondal
 
Friend function
Friend functionFriend function
Friend function
zindadili
 
Function overloading
Function overloadingFunction overloading
Function overloading
Selvin Josy Bai Somu
 
06. operator overloading
06. operator overloading06. operator overloading
06. operator overloading
Haresh Jaiswal
 
Looping in c language
Looping in c languageLooping in c language
Looping in c language
Infinity Tech Solutions
 
Java abstract class & abstract methods
Java abstract class & abstract methodsJava abstract class & abstract methods
Java abstract class & abstract methods
Shubham Dwivedi
 
Variables in C++, data types in c++
Variables in C++, data types in c++Variables in C++, data types in c++
Variables in C++, data types in c++
Neeru Mittal
 
C# Framework class library
C# Framework class libraryC# Framework class library
C# Framework class library
Prem Kumar Badri
 
Deep C
Deep CDeep C
Deep C
Olve Maudal
 
virtual function
virtual functionvirtual function
virtual function
VENNILAV6
 
C# classes objects
C#  classes objectsC#  classes objects
C# classes objects
Dr.Neeraj Kumar Pandey
 
friend function(c++)
friend function(c++)friend function(c++)
friend function(c++)
Ritika Sharma
 
07. Virtual Functions
07. Virtual Functions07. Virtual Functions
07. Virtual Functions
Haresh Jaiswal
 
Exception handling in java
Exception handling in javaException handling in java
Exception handling in java
Pratik Soares
 
C++ Files and Streams
C++ Files and Streams C++ Files and Streams
C++ Files and Streams
Ahmed Farag
 

What's hot (20)

What is Switch Case?
What is Switch Case?What is Switch Case?
What is Switch Case?
 
Virtual function in C++ Pure Virtual Function
Virtual function in C++ Pure Virtual Function Virtual function in C++ Pure Virtual Function
Virtual function in C++ Pure Virtual Function
 
Type Conversion, Precedence and Associativity
Type Conversion, Precedence and AssociativityType Conversion, Precedence and Associativity
Type Conversion, Precedence and Associativity
 
Advanced Programming C++
Advanced Programming C++Advanced Programming C++
Advanced Programming C++
 
C++20 features
C++20 features C++20 features
C++20 features
 
If-else and switch-case
If-else and switch-caseIf-else and switch-case
If-else and switch-case
 
Friend function
Friend functionFriend function
Friend function
 
Function overloading
Function overloadingFunction overloading
Function overloading
 
06. operator overloading
06. operator overloading06. operator overloading
06. operator overloading
 
Looping in c language
Looping in c languageLooping in c language
Looping in c language
 
Java abstract class & abstract methods
Java abstract class & abstract methodsJava abstract class & abstract methods
Java abstract class & abstract methods
 
Variables in C++, data types in c++
Variables in C++, data types in c++Variables in C++, data types in c++
Variables in C++, data types in c++
 
C# Framework class library
C# Framework class libraryC# Framework class library
C# Framework class library
 
Deep C
Deep CDeep C
Deep C
 
virtual function
virtual functionvirtual function
virtual function
 
C# classes objects
C#  classes objectsC#  classes objects
C# classes objects
 
friend function(c++)
friend function(c++)friend function(c++)
friend function(c++)
 
07. Virtual Functions
07. Virtual Functions07. Virtual Functions
07. Virtual Functions
 
Exception handling in java
Exception handling in javaException handling in java
Exception handling in java
 
C++ Files and Streams
C++ Files and Streams C++ Files and Streams
C++ Files and Streams
 

Similar to Hot C++: Rvalue References And Move Semantics

[OLD VERSION, SEE DESCRIPTION FOR NEWER VERSION LINK] Hot C++: Rvalue Referen...
[OLD VERSION, SEE DESCRIPTION FOR NEWER VERSION LINK] Hot C++: Rvalue Referen...[OLD VERSION, SEE DESCRIPTION FOR NEWER VERSION LINK] Hot C++: Rvalue Referen...
[OLD VERSION, SEE DESCRIPTION FOR NEWER VERSION LINK] Hot C++: Rvalue Referen...
Andrey Upadyshev
 
C++ references
C++ referencesC++ references
C++ references
corehard_by
 
Elements of C++11
Elements of C++11Elements of C++11
Elements of C++11
Uilian Ries
 
Hot C++: New Style of Arguments Passing
Hot C++: New Style of Arguments PassingHot C++: New Style of Arguments Passing
Hot C++: New Style of Arguments Passing
Andrey Upadyshev
 
C++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect ForwardingC++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect Forwarding
Francesco Casalegno
 
C++11 move semantics
C++11 move semanticsC++11 move semantics
C++11 move semantics
Arindam Mukherjee
 
Gentle introduction to modern C++
Gentle introduction to modern C++Gentle introduction to modern C++
Gentle introduction to modern C++
Mihai Todor
 
gdscWorkShopJavascriptintroductions.pptx
gdscWorkShopJavascriptintroductions.pptxgdscWorkShopJavascriptintroductions.pptx
gdscWorkShopJavascriptintroductions.pptx
sandeshshahapur
 
The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019
The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019
The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019
corehard_by
 
1669958779195.pdf
1669958779195.pdf1669958779195.pdf
1669958779195.pdf
venud11
 
JavaScript Cheatsheets with easy way .pdf
JavaScript Cheatsheets with easy way .pdfJavaScript Cheatsheets with easy way .pdf
JavaScript Cheatsheets with easy way .pdf
ranjanadeore1
 
Unit 3-Javascript.pptx
Unit 3-Javascript.pptxUnit 3-Javascript.pptx
Unit 3-Javascript.pptx
AmanJha533833
 
Memory Management with Java and C++
Memory Management with Java and C++Memory Management with Java and C++
Memory Management with Java and C++Mohammad Shaker
 
ARC - Moqod mobile talks meetup
ARC - Moqod mobile talks meetupARC - Moqod mobile talks meetup
ARC - Moqod mobile talks meetup
Moqod
 
Compilation and Execution
Compilation and ExecutionCompilation and Execution
Compilation and Execution
Chong-Kuan Chen
 
What's New in C++ 11?
What's New in C++ 11?What's New in C++ 11?
What's New in C++ 11?
Sasha Goldshtein
 
Esoft Metro Campus - Programming with C++
Esoft Metro Campus - Programming with C++Esoft Metro Campus - Programming with C++
Esoft Metro Campus - Programming with C++
Rasan Samarasinghe
 

Similar to Hot C++: Rvalue References And Move Semantics (20)

[OLD VERSION, SEE DESCRIPTION FOR NEWER VERSION LINK] Hot C++: Rvalue Referen...
[OLD VERSION, SEE DESCRIPTION FOR NEWER VERSION LINK] Hot C++: Rvalue Referen...[OLD VERSION, SEE DESCRIPTION FOR NEWER VERSION LINK] Hot C++: Rvalue Referen...
[OLD VERSION, SEE DESCRIPTION FOR NEWER VERSION LINK] Hot C++: Rvalue Referen...
 
C++ references
C++ referencesC++ references
C++ references
 
Elements of C++11
Elements of C++11Elements of C++11
Elements of C++11
 
Hot C++: New Style of Arguments Passing
Hot C++: New Style of Arguments PassingHot C++: New Style of Arguments Passing
Hot C++: New Style of Arguments Passing
 
C++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect ForwardingC++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect Forwarding
 
C++11 move semantics
C++11 move semanticsC++11 move semantics
C++11 move semantics
 
Gentle introduction to modern C++
Gentle introduction to modern C++Gentle introduction to modern C++
Gentle introduction to modern C++
 
gdscWorkShopJavascriptintroductions.pptx
gdscWorkShopJavascriptintroductions.pptxgdscWorkShopJavascriptintroductions.pptx
gdscWorkShopJavascriptintroductions.pptx
 
The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019
The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019
The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019
 
1669958779195.pdf
1669958779195.pdf1669958779195.pdf
1669958779195.pdf
 
JavaScript Cheatsheets with easy way .pdf
JavaScript Cheatsheets with easy way .pdfJavaScript Cheatsheets with easy way .pdf
JavaScript Cheatsheets with easy way .pdf
 
Unit 3-Javascript.pptx
Unit 3-Javascript.pptxUnit 3-Javascript.pptx
Unit 3-Javascript.pptx
 
Memory Management with Java and C++
Memory Management with Java and C++Memory Management with Java and C++
Memory Management with Java and C++
 
ARC - Moqod mobile talks meetup
ARC - Moqod mobile talks meetupARC - Moqod mobile talks meetup
ARC - Moqod mobile talks meetup
 
Compilation and Execution
Compilation and ExecutionCompilation and Execution
Compilation and Execution
 
What's New in C++ 11?
What's New in C++ 11?What's New in C++ 11?
What's New in C++ 11?
 
Introduction to php basics
Introduction to php   basicsIntroduction to php   basics
Introduction to php basics
 
Esoft Metro Campus - Programming with C++
Esoft Metro Campus - Programming with C++Esoft Metro Campus - Programming with C++
Esoft Metro Campus - Programming with C++
 
C_plus_plus
C_plus_plusC_plus_plus
C_plus_plus
 
Unit 2.5
Unit 2.5Unit 2.5
Unit 2.5
 

Recently uploaded

Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
Globus
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Ortus Solutions, Corp
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
Globus
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
XfilesPro
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
ShamsuddeenMuhammadA
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Globus
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Globus
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
Globus
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
Donna Lenk
 

Recently uploaded (20)

Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
 

Hot C++: Rvalue References And Move Semantics

  • 1. Andrey Upadyshev Hot C++:
 Rvalue References And Move Semantics Licensed under a CC BY-SA 4.0 License. Version of 2019.04.30 !1
  • 2. Overview ❖ Rvalue references ❖ Move semantics ❖ It’s well assisted! ❖ More ways to shoot yourself in the foot !2
  • 4. Lvalue And Rvalue (how came from C) • lvalue - may appear on the left hand side of an assignment, represents storage region locator value, i.e. evaluates to object identity. • All the rest is non-lvalue or rvalue (because can appear on the right hand side of assignment only) !4
  • 5. Lvalue And Rvalue, Example 1 int a = 42; // OK lvalue on left side of assignment int b = 43; // and rvalue on right side a = b; // OK, lvalue may be on any side of assignment b = a; // OK, lvalue may be on any side of assignment int c = a * b; // OK, rvalue on right side of assignment a * b = 42; // err, rvalue on left hand side of assignment int *p = &i; // OK, i is an lvalue int *p1 = &43; // err, cannot take the address of an rvalue !5
  • 6. Value Categories (C++11) • lvalue - is an expression that identifies a non-temporary object • prvalue ("pure" rvalue) - is an expression that identifies a temporary object or is a value not associated with any object (C++03 rvalue) • Ex: The result of calling a function whose return type is a value • xvalue (an “eXpiring” value) - is an expression that identifies expiring object, that is, the object that may be moved from • Ex: The result of calling a function whose return type is an rvalue reference !6 Simplified! }rvalues
  • 7. std::cout << &bar().member; // ? Lvalue And Rvalue, Example 2 Foo& foo(); // `foo()` is lvalue
 foo() = 42; // OK
 std::cout << &foo(); // OK Bar bar(); // `bar()` is prvalue
 Bar && pub(); // `pub()` is xvalue
 Bar b2 = bar(); // OK
 bar() = b2; // cannot assign to an rvalue
 std::cout << &bar(); // cannot take the address of an rvalue
 std::cout << &pub(); // … !7 std::cout << &bar().member; // reference to a member of an rvalue
 // is an rvalue!
  • 8. Lvalue References void foo(const Bar& bar); //[1]
 Binds to lvalue and rvalue. Can not modify bar. void foo(Bar& bar); //[2]
 Binds to lvalue only. Can modify bar. (Very old Visual C++ versions bind it to rvalue too. But this does not conform to the Standard) !8 Bar read_bar(const char *filename); foo(read_bar(“bar.txt”)); ? foo(read_bar(“bar.txt”)); // [1] => bar is const
  • 9. Rvalue References !9 void foo(const Bar& bar); //[1] Binds to lvalue and rvalue. Can not modify bar. void foo(Bar& bar); //[2] Binds to lvalue only. Can modify bar. void foo(Bar && bar); //[3] Binds to rvalue only. Takes precedence over lvalue overloads. Can modify bar. void foo(const Bar && bar); //[4] Binds to rvalue only. Takes precedence over lvalue overloads. Can not modify bar. [Almost] has no useful meaning. Use const ref overload instead. foo(read_bar(“bar.txt”)); // [3] => bar is mutable!
  • 10. Why Do I Need Them At All? void foo(Bar && rv); ❖ In short: to use move semantics! ❖ Longer: ❖ Because rvalue references bind to rvalue, they can be used to extend the lifetime of a modifiable temporary (an rvalue is a temporary, remember?). ❖ You can do funny things with temporary, e.g. safely steal any data you need from it (nobody cares, heh). It’s called move semantics. !10
  • 12. Move Semantics In Example Copying MemBuf lv = rv; class MemBuf { void *m_data; size_t m_size; ... }; !12 F1 23 4C DB 98 73 11 ... rv allocate and copy F1 23 4C DB 98 73 11 ... lv contains a copy of rv's content lv Moving MemBuf lv = std::move(rv); F1 23 4C DB 98 73 11 ... rv lv lv grabs (steals) content of rv rv in moved-from state X
  • 13. Moved-From Objects ❖ Moving-from does not abolish destructing. The object’s destructor is be called anyway! ❖ Moved-from object should be placed in a valid but unspecified state, so it is safe to: ❖ destroy it ❖ assign one a new value (is assignable) ❖ A type may provide more strong guaranty. E.g. there is guaranty that moved-from STD smart pointers are empty. !13 F1 23 4C DB 98 73 11 ... rv lv X
  • 14. Why Move Semantics? The best possible performance for classes with expensive copy while keeping the clear interface. ❖ std::vector<HugeObject> performing bad in C++03: ❖ Copies elements on insertion and even more on growing. ❖ Can be passed around only wrapped with smart pointer. ❖ So we used std::vector<std::shared_ptr<HugeObject>> or boost::ptr_vector<HugeObject> to gain performance but got new problems: ❖ Extra allocation and extra level of indirection (performance!) ❖ Extra complexity ❖ Doesn’t work smoothly with STL algorithms (OK, ptr_vector does) ❖ Thanks to move semantics std::vector<HugeObject> become good in C++11 (finally!): ❖ Elements are moved on insertion and on growing ❖ No [smart] pointer involved overhead ❖ Clear and simple, STL algorithms works perfect ❖ Can be moved around !14
  • 15. Why Move Semantics? ❖ Cleaner interface for non-copyable but movable objects (like files, threads etc): ❖ std::auto_ptr<File> openFile(
 const char *filename); // C++03 ❖ File openFile(const char *filename); // C++11 !15
  • 16. Adding Move Semantics To a Class ❖ There are two new special member functions: ❖ Move constructor:
 Foo::Foo(Foo&& op); ❖ Move assignment operator:
 Foo& operator= (Foo&& op); ❖ Like copy ctor/assignment operator, but moves from its argument. ❖ The functions are compiler generated by default (use it!) but may be user provided, explicitly defaulted or deleted. ❖ Compiler uses similar rules as for copy ctor/copy assignment operator generation. ❖ Visual Studio before 2015 does not generate move ctor/move assignment. You must do it manually. !16
  • 17. Forcing Move Semantics template<class T>
 void swap_opt(T& a, T& b)
 {
 T tmp(a);
 a = b;
 b = tmp;
 } Hm, copying… std::move just casts lvalue to rvalue (no moving itself!) what allows a move semantics to be used. Scott Meyers said that perhaps one should be called rvalue_cast !17 template<class T>
 void swap_opt(T& a, T& b)
 { 
 T tmp(std::move(a));
 a = std::move(b);
 b = std::move(tmp);
 } Moving!!! Let’s implement optimized swap that utilize move semantics. For simplicity, assume that it will be applied only to movable types. Forcing move semantics leaves moved from objects behind, so must be uses carefully: std::string tmp("bla-bla");
 std::string s(std::move(tmp));
 std::cout << tmp; // Using of 'moved from' object (e.g. by mistake) for
 // other then assigning. Undefined behavior for most types
  • 19. Supported By STL ❖ C++11 STL is significantly extended to support rvalue references and move semantics: ❖ All containers and other types storing user types (pair, tuple, future, function, smart pointers etc) are move-aware. ❖ New algorithms: move, move_forward ❖ New iterator adapter: move_iterator ❖ Movable, non-copyable unique_ptr replaces flawy auto_ptr (which is deprecated) ❖ Optimized swap for movable types ❖ New type traits !19
  • 20. Ref Qualifiers ❖ Member functions can be specified with ref-qualifier & or &&, placed after cv-qualifier: ❖ const Foo& Bar::foo() const & { // [1]
 return m_foo;
 } ❖ Foo&& Bar::foo() && { // [2]
 return std::move(m_foo); // `*this` is always
 } // lvalue ❖ Allow to have different overloads for lvalue and rvalue (temporary). ❖ No ref-qualifier means “whatever” (for backward compatibility) ❖ A function with a ref-qualifier can not overload with a function without one. !20
  • 21. Perfect Forwarding & Forwarding References ❖ Perfect forwarding is finally possible! ❖ Thanks to forwarding (aka universal) references and new reference collapsing rules: ❖ template<class P1, class P2>
 void create_foo(P1 && p1, P2 && p2) {
 Foo foo(std::forward<P1>(p1),
 std::forward<P2>(p2));
 …
 } ❖ Looks even better with variadic templates (not a sarcasm!) ❖ It is a big topic for another talk !21
  • 22. Optimization ❖ Copy elision does elision of both copy and move operations ❖ When copy elision is not applicable, compiler prefers moving over copying. !22
  • 23. Special Member Functions ❖ Move constructor and move assignment operator aren’t generated if copy constructor, copy assignment operator or destructor is explicitly declared. ❖ Copy constructor and copy assignment operator aren't generated if move constructor or move assignment operator is explicitly declared ❖ Not supported before Visual Studio 2015 ❖ Rule of three become rule of five:
 If a class defines one of the following it should probably explicitly define all five: •destructor •copy constructor •copy assignment operator •move constructor •move assignment operator !23
  • 24. More Ways To Shoot Yourself In The Foot !24
  • 25. Named Rvalue Reference Is Not an Rvalue Foo::Foo(Bar && bar)
 : m_bar(bar) {} //[1] Is something wrong? Named rvalue reference identifies an object => it is lvalue.
 i.e. bar is copied unless move semantics is forced Foo::Foo(Bar && bar)
 : m_bar(std::move(bar)) {} //[2] OK Foo::Foo(Foo && rh)
 : m_bar(rh.m_bar) {} //[3] copy, ref to lvalue member is an lvalue Foo::Foo(Foo && rh)
 : m_bar(std::move(rh.m_bar)) {} //[4] OK
 // or even safer
 : m_bar(std::move(rh).m_bar) {} //[5] OK, ref to rvalue member is
 // rvalue !25
  • 26. Returning of Rvalue Reference Foo && make_foo() { //[1] Is something wrong?
 return Foo(42);
 } An rvalue reference is a reference. Returning a reference to a local object is bad. Return by value instead Foo make_foo() { //[2] OK
 return Foo(42);
 } Return rvalue reference only when you really know that you need this. A right example is std::move: template<class T>
 typename std::remove_reference<T>::type&& std::move(T && t) {
 return static_cast<typename std::remove_reference<T>::type &&>(t);
 } !26
  • 27. ❖ Applying std::move to a const object does not activate move semantics! You quietly got copy instead of move. ❖ const Foo f = make_foo();
 return Bar(std::move(f));
 // Moving of `f` is blocked ❖ std::move does not remove object constness ❖ No compilation error generated in such case. ❖ Confusing unjustified behavior. One can write something like safe_move to protect himself. std::move And Const Objects !27
  • 28. Move Semantics and RVO !28 struct Foo {…}; Foo make_foo1() {
 Foo r(…);
 return std::move(r);
 } Everything correct? RVO is blocked, r is moved or copied Foo make_foo1() {
 Foo r(…);
 return r;
 } RVO is applied, no move or copy
  • 29. Move Semantics and RVO !29 struct Bar {…}; struct Foo {
 Foo(const Bar& rh);
 Foo(Bar && rh);
 …
 }; Foo make_foo2() { Bar bar(…); return bar;
 } Everything correct? Actually it is `return Foo(bar)`. bar is copied Foo make_foo2() { Bar bar(…); return std::move(bar);
 } Actually it is `return Foo(std::move(bar))`. bar is moved. We can’t get any better here
  • 30. Move Semantics And Exception Safety ❖ // Huge object
 struct Elephant {
 Elephant(const Elephant& op);
 Elephant(Elephant && op);
 Elephant& operator= (const Elephant& op);
 Elephant& operator= (Elephant && op);
 …
 };
 
 std::vector<Elephant> all_elephants;
 … // Heavily use it ❖ Does everything look good? !30
  • 31. Move Semantics And Exception Safety For good reason STL containers may copy elements internally unless ones' move constructor doesn't throw. Special traits are used: std::move_if_noexcept std::is_nothrow_move_constructible To get rid of copy, add noexcept to the move special functions (only if function really doesn't throw, no cheating, please!): Elephant(Elephant && op) noexcept; Note that noexcept is not supported in Visual Studio before 2015, use macro like BOOST_NOEXCEPT (<boost/config/suffix.hpp>): Elephant(Elephant && op) BOOST_NOEXCEPT; !31
  • 32. Useful Links Alex Allain, Move semantics and rvalue references in C++11
 http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html Dave Abrahams, Exceptionally Moving!
 http://web.archive.org/web/20130524084627/http://cpp-next.com/archive/2009/10/exceptionally-moving/ Stephan T. Lavavej, Don’t Help the Compiler
 http://channel9.msdn.com/Events/GoingNative/2013/Don-t-Help-the-Compiler Andrzej Krzemieński, Ref-qualifiers
 https://akrzemi1.wordpress.com/2014/06/02/ref-qualifiers/ Max Galkin. C++ curiosities: one does not simply move a const object
 http://yacoder.net/blog/2015/05/06/cpp-curiosities-one-does-not-simply-move-a-const-object/ C++ Reference
 http://en.cppreference.com/w/ Value categories
 https://en.cppreference.com/w/cpp/language/value_category C++11 Standard (final plus minor editorial changes) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf !32
  • 33. Questions? !33 I HAVE NO IDEA
 WHAT’S GOING ON.