Back to Basics: Move Semantics (part 1 of 2) - Klaus Iglberger - CppCon 2019

Ғылым және технология

CppCon.org
Discussion & Comments: / cpp
Presentation Slides, PDFs, Source Code and other presenter materials are available at: github.com/CppCon/CppCon2019
-
Back to Basics: Move Semantics (part 1 of 2)
Move semantics is one of the most complex topics in the world of C++, including many technical details that often confuse even experts. This interactive back-to-the-basics session is entirely focused on understanding the details behind move semantics. It explains the motivation behind move semantics, the need for rvalue references and std::move, the reason for forwarding references and std::forward, and how to properly apply move semantics. The many interactive questions and exercises will help to quickly adapt the newly gained knowledge.
-
Klaus Iglberger
Klaus Iglberger is a freelancing C++ trainer and consultant and is currently on the payroll of Siemens in Nuremberg, Germany. He has finished his PhD in computer science in 2010 and since then is focused on large-scale C++ software design. He shares his experience in popular advanced C++ courses around the world (mainly in Germany, but also the EU and US). Additionally, he is the initiator and lead designer of the Blaze C++ math library (bitbucket.org/blaze-lib/blaze...) and the organizer of the Munich C++ user group (www.meetup.com/MUCplusplus/).
-
Videos Filmed & Edited by Bash Films: www.BashFilms.com
*-----*
*--*
*-----*

Пікірлер: 78

  • @norikazuoshiro6324
    @norikazuoshiro63244 жыл бұрын

    Man i really love these back to basics series talks (specially this one and the RAII by Arthur). Helps me a lot as C++ beginner

  • @landondyer

    @landondyer

    3 жыл бұрын

    I've been using C++ since the 1980s, and it still helps me :-)

  • @masheroz

    @masheroz

    2 жыл бұрын

    This one? kzread.info/dash/bejne/aYWbxpt7Ya7bfbQ.html

  • @atib1980

    @atib1980

    Жыл бұрын

    @@landondyer I had to learn C++ programming back in 2002 - 2003 for my 3rd year University subject called OOP and data structures. After I had passed that exam I didn't really use C++ for about 10 years. Picked it up again sometime in 2014-2015 when I decided I needed to dive deeper into the gritty - nitty details of C++'s language semantics, syntax rules and the C++ memory model. Have been using this wonderful powerful programming language ever since. I really love all the modern C++ language features especially those that were introduced with the first 3 modern C++ language standards (C++11, C++14 and C++17). At the moment I'm in the process of getting acquainted with all the new C++ language and library features that were introduced with the C++ 20 standard.

  • @b1ueocean

    @b1ueocean

    Жыл бұрын

    @@atib1980 we did OOP in my second year as 1st year Intro to Programming switched to Java - our learning materials were still in pre-print. Like you, after uni I left C/C++ behind - but I had been doing C/C++/ASM since I was 15. I’m shocked that the language, although “modernised”, still looks absolutely horrible to read and requires several scans of lines, parameters, modifiers, syntaxes and so on to properly figure out what code is doing. Not looks like it is doing but is actually doing. My SAAS backend is in C++ interfacing with a SPA Frontend. For the sanity of myself and others, functionality at the back relies heavily on an in-house framework to standardise everything - die hard C++ers will use and abuse everything available if you let them and render the codebase horrible for consumption by others that know it pays to keep things simple 🙂 I do love the performance I get at runtime though - my end to end round trips are lightening fast allowing the Frontend to operate extremely responsively and seamlessly 👍 One thing I had to sort out straight away was dependency management and build workflow. Ended up throwing away makefiles and using Maven which has been ok so far. “mvn clean package” gives me shareable libraries and executable binaries for AMD64, AARCH64, Linux and Windows with compile-time Native ARchive dependencies pulled in from a Nexus repo 🙏

  • @robertfreeman2792
    @robertfreeman27922 жыл бұрын

    As someone who was in the group of not knowing what move semantics are, I now feel like I understand them! Essentially, skip the copy constructor call, skip the temporary object creation and simply call the move constructor for increased performance. Set the old pointer to nullptr in the move constructor.

  • @Gloryisfood
    @Gloryisfood2 жыл бұрын

    Best move semantics video I've ever seen!

  • @bodguy1035
    @bodguy10354 жыл бұрын

    this talk is actually very good explanation about weird part of move semantics

  • @bobbymah2682
    @bobbymah26824 жыл бұрын

    Great talk! Cleared up details for me, thanks

  • @pmcgee003
    @pmcgee0034 жыл бұрын

    The move operator is actually an eviction operator. :) I'm taking your house.

  • @francescocapano6732

    @francescocapano6732

    4 жыл бұрын

    Seems more of a burglar operator to me. I'm taking everything from your house, you're welcome.

  • @CookiePepper

    @CookiePepper

    2 жыл бұрын

    It is just a title transfer instead of building the same house.

  • @Evan490BC

    @Evan490BC

    2 жыл бұрын

    It's more like "I am transforming my house into a caravan so that it can move". The std::move function is essentially a static_cast.

  • @tourdesource
    @tourdesource Жыл бұрын

    [46:15] "You don't really have to protect against move to self" Well, unless you're holding a pointer to a Widget. Then if you do w = std::move(*w.pw), you end up deleting the thing you're trying to move from, which is not exactly self-assignment but still dangerous. Arthur O'Dwyer explains this situation in his talk about RAII, also from CppCon 2019, and presents it as a justification for preferring the std::swap method.

  • @sezerbaglan1804
    @sezerbaglan18044 жыл бұрын

    The best explanation ever!

  • @christoj
    @christoj Жыл бұрын

    Thank you, excellent talk, very easy to understand.

  • @marcospatton
    @marcospatton2 жыл бұрын

    Great talk !!! very clearned up details for me.

  • @RaymondHulha
    @RaymondHulha4 жыл бұрын

    Super awesome Video! Thank you for sharing! Vielen Dank :)

  • @lwrcica5
    @lwrcica54 жыл бұрын

    Great presentation!

  • @SuhailKhan-vr6ik
    @SuhailKhan-vr6ik4 жыл бұрын

    Excellent talk!

  • @sushillakra21
    @sushillakra212 жыл бұрын

    Excellent talk, I came to learn new things which help me improve my own project! Thanks :)

  • @CppCon

    @CppCon

    2 жыл бұрын

    Great to hear!

  • @dechencheng8847
    @dechencheng88473 жыл бұрын

    excellent talk!

  • @Vermilicious
    @Vermilicious4 жыл бұрын

    Another reason to avoid raw pointers? I think so.

  • @codefool3022
    @codefool30224 жыл бұрын

    Small correction - @53:16 He mentions Core Guideline C.15. There is no C.15 (yet) - he meant F.15.

  • @joesilver75
    @joesilver754 жыл бұрын

    Thank you for using the uniform initialization.

  • @joesilver75

    @joesilver75

    4 жыл бұрын

    ...but not in the member initializer list :-(

  • @ivancheburan2209
    @ivancheburan2209 Жыл бұрын

    According to core guidelines C.65 in the example of Widget's move assignment operator he should have added a simple check for self-reference, it would solve problem pointed out by a woman from the audience.

  • @Stierguy1
    @Stierguy14 жыл бұрын

    I'm so sad that Klaus didn't mention that you can do std::move(w).i and std::move(w).s. The members of an rvalue are rvalues!

  • @sukraatahluwalia5137

    @sukraatahluwalia5137

    4 жыл бұрын

    Wouldn't i(w.i) be not a move since int is a trivially copyable type, and move on such types is a no-op?

  • @manuelvalencia6705
    @manuelvalencia67057 ай бұрын

    illuminating

  • @kpopisthebestful
    @kpopisthebestful4 жыл бұрын

    But what if you had Widget as a data member and in the move assignment/copy, you do this->widget = std::move(Widget&& w);. Wouldnt this cause some infinite loop? In that case would i just have to do this->widget = w.widget and have no other choice but to use copy constructor?

  • @sureshm8289
    @sureshm82894 жыл бұрын

    wow great video. and where can I get information about the coding guidelines which you were referring about?

  • @raymondyoo5461

    @raymondyoo5461

    3 жыл бұрын

    Maybe cppcoreguidelines??

  • @liveonphoenix5045
    @liveonphoenix50452 жыл бұрын

    @18:34, private var i, s, or pi. The default move-constructor or default assign move-operator, what will happens to the previous var/fields are they being reset like this? w.i = 0, w.s = NULL, w.pi = nullptr. Is this right?

  • @GeorgeTsiros
    @GeorgeTsiros4 жыл бұрын

    so many good things about this presentation (audio, voice, articulation, rhythm etc), it breaks my heart to say that without seeing how exactly the statements are compiled and how exactly the memory is managed under the hood, i can't follow it.

  • @TheLeontheking

    @TheLeontheking

    4 жыл бұрын

    Showing that would probably have left behind a good part of the audience...

  • @liveonphoenix5045
    @liveonphoenix50452 жыл бұрын

    I have a quick question. What happens if the previous variable is now empty? Even though it is empty, it retains a specific size and cannot become an external resource to other processes until it is no longer in scope.

  • @liveonphoenix5045

    @liveonphoenix5045

    2 жыл бұрын

    If we have dynamic memory, we can manually free it or reuse it for other purposes. However, in RAI Initialization, it will be freed as soon as the scope is finished.

  • @rahuldeshmukhpatil
    @rahuldeshmukhpatil2 жыл бұрын

    at 28:10, does he mean "If I do not make *move* constr noexpcet" ? he said "copy constr".

  • @Lecker9419
    @Lecker94193 жыл бұрын

    At 45:32, can it be that the passed in object (w)'s destructor gets called while you are move-ing its fields and potentially move garbage to *this object?

  • @D0Samp

    @D0Samp

    2 жыл бұрын

    Not under normal conditions, since the object will not go out of scope as long as the move assignment operator holds a reference to it. An rvalue&& reference behaves the same as a lvalue& reference in that regard.

  • @player-eric
    @player-eric Жыл бұрын

    By the way, how can I find the implementation of std::move like you did?

  • @Webfra14
    @Webfra144 жыл бұрын

    @51:47 - Why is there no point in move operations for virtual classes?

  • @ALX112358

    @ALX112358

    4 жыл бұрын

    It would make sense only if both classes were of the same type. But what if you know only a common base class? It is either unsafe, or you need a dynamic cast with exception when dynamic cast fails. It is a troublesome situation no matter how you look at it.

  • @pralaypatoria1352
    @pralaypatoria13522 жыл бұрын

    Do we really need std::move(w.pi); ? pi=w.pi; should what we require ? eventually pi=std::move(w.pi) will do the same as its just a static cast and its relevant for class objects so that their move operators are called but not relevant for pointers. please correct me if wrong. delete pi; isn't incorrect? it should be delete[] pi;? assuming you used int* to allocate dynamic array?

  • @Antagon666
    @Antagon666 Жыл бұрын

    I find tutorials on this topic very lacking. First time ever hearing about noexcept for example. Or the move constructors, where you have to call move anyways. I wonder if it's possible for standard to implement automatical moves where you don't need copy (passing temporary variables through series of const ref parameters in nested function calls for example).

  • @saichandu8178
    @saichandu81789 ай бұрын

    one question I have is, how does a chained move assignment works?

  • @fredrikorderud
    @fredrikorderud4 жыл бұрын

    I usually prefer to call the destructor explicitly when implementing move assignment operators. That way, I avoid duplication of the resource cleanup code. However, this doesn't seem to be common practice. Are there any arguments (besides performance) against calling the destructor in move assignment operators?

  • @Stierguy1

    @Stierguy1

    4 жыл бұрын

    According to the standard, the lifetime of an object ends when its destructor is called, and use after lifetime is UB. Roughly, incurring this kind of UB may lead to the compiler breaking your program. If you manually invoke the destructor for any object, you must construct a new object in that memory before you can re-use it; if that object is a stack object, you must do so using placement new, and you must do so before the destructor is automatically invoked (this is mandatory, the destructor must not be called after the end of the object's lifetime). If a move assignment operator manually invokes the destructor, it must immediately construct a new object at the this pointer using placement new.

  • @fredrikorderud

    @fredrikorderud

    4 жыл бұрын

    @Ted Thanks a lot for the explanation! Do you then agree that the following could serve as a canonical move-assignment implementation, disregarding performance and assuming that a noexcept move-constructor is available? TYPE& operator = (TYPE&& other) noexcept { TYPE::~TYPE(); new(this) TYPE(std::move(other)); return *this; }

  • @fredrikorderud

    @fredrikorderud

    4 жыл бұрын

    I've now moved an updated version of this question to stackoverflow.com/questions/58280104/canonical-c-assignment-operators that incorporates the feedback from @Ted.

  • @movaxbx656
    @movaxbx6562 жыл бұрын

    Around minute 45, about the move to self problem. Using std::swap() wouldn't make it safe and the object invariant since the pointer wouldn't be deleted?

  • @dennydaydreamer

    @dennydaydreamer

    Жыл бұрын

    By unsafe you probably mean that the original value in *pi is lost, and therefore you would prefer the swap implementation. I think Klaus's argument is that if you write w = std::move(w), then you are expressing the idea that you no longer care about the value in w, therefore it is okay to release the memory in pi and reset it to nullptr. Either approach is fine and he indeed say you need to make a decision based on what you want. He also points out that one caveat of the swap implementation is that the memory of the assigned to object is not immediately released, which I think is an important point to note because you are relying on a properly written constructor to do the work.

  • @Dante3085
    @Dante30853 жыл бұрын

    ~ 16:20 Why does move take an rvalue reference "T&& t" if it is supposed to return an rvalue reference ?

  • @dennisrkb

    @dennisrkb

    3 жыл бұрын

    that's a universal reference which can bind to anything. check out Scott Meyers' book and talks..

  • @MUCplusplus

    @MUCplusplus

    3 жыл бұрын

    std:move() takes a forwarding reference, not an rvalue reference. Please see the second part of your talk, which covers forwarding references in detail.

  • @pedantic79
    @pedantic794 жыл бұрын

    53:21 that should be F.15 not C.15

  • @raymondyoo5461
    @raymondyoo54613 жыл бұрын

    53:30 why std::array is 'expensive' to move???

  • @dennisrkb

    @dennisrkb

    3 жыл бұрын

    because the only way to 'move' it is to copy it, it's a value type.

  • @hubertbonnisseur-de-la-bat4858
    @hubertbonnisseur-de-la-bat48589 ай бұрын

    I don't get it, at which point s + s = s is valid ?

  • @Quuxplusone
    @Quuxplusone4 жыл бұрын

    Part 2 is here: kzread.info/dash/bejne/on2uw7ybe7jdYtY.html

  • @HelloMisraji
    @HelloMisraji2 жыл бұрын

    Wouldn't the code of self-move assignment operator result in a dangling pointer?

  • @D0Samp

    @D0Samp

    2 жыл бұрын

    While the deleted pointer is indeed moved to itself, it also gets set to nullptr in the moved-from object at the end, leaving nothing behind. One advantage of std::swap over explicit nulling is that you get to keep the allocation in this case.

  • @hidayatrzayev6603

    @hidayatrzayev6603

    2 жыл бұрын

    @@D0Samp How does that answer the question? I was also wondering about a dangling pointer. If we assign to self, and delete the pointer in the beginning of the move assignment operator, then essentially the object that we're moving from (ourselves) would also have a pointer that points to nowhere, which we would try to move to our object, resulting in a dangling pointer. How does std::swap help here?

  • @rabingajmer3293

    @rabingajmer3293

    Жыл бұрын

    With the move assignment from the video, we will end up having a nullptr which is not transferring ownership at all. I think the presenter didn't understand the question that the woman asked properly.

  • @jamessilva8331
    @jamessilva83314 жыл бұрын

    Hey just wanted to add that the delete pi around the 40:00 minute mark would likely be a delete[ ] pi in practice because the pi was likely created with a new [ ].

  • @esra_erimez
    @esra_erimez3 жыл бұрын

    I have to say, that when a language needs an hour long two part video on basic functionality such as move, there is something fundamentally wrong with it.

  • @absurdengineering

    @absurdengineering

    3 жыл бұрын

    C++ is many languages in one, including C. The talk covers that - it can’t just presume that you will only use the modern parts and ignore all else.

  • @pedrov8868

    @pedrov8868

    2 жыл бұрын

    Is it that basic though?

  • @b1ueocean

    @b1ueocean

    Жыл бұрын

    It’s an absolutely horrible language - there is no doubt about that 🙂 I’ve just mandated it as the primary development language at my startup, side-stepping go, rust, zig, carbon et al, so I must be absolutely horrible too 😂 20+ years doing Java which has become horrible in different ways led me to take another look at C/C++… it’s a completely different beast to when I was doing game and graphics engines in Borland, Watcom, TASM and MASM back in the day. Windows API, MFC and COM programming using Hungarian syntax all of a sudden doesn’t seem that bad at all compared to this b.s. they are actually calling “modern”. A modern nightmare with jobs that don’t pay anywhere near enough to justify the cognitive (over)load and management/maintenance headaches. I’ve had 5 segfaults due to bad inputs this week, the last time I had a program crash out at runtime this way was 1999 🤷‍♂️ Hello Again C++ World 💩

  • @iliasalaur

    @iliasalaur

    6 ай бұрын

    well, what do you think why nobody uses JS for let’s say commercial embedded development? Some languages need to be hard, in order to endow the programmer with superpowers. But as it was said, with great power comes a greater responsibility

  • @muhdiversity7409

    @muhdiversity7409

    4 ай бұрын

    Esra, I've seen you comments on other channels and I totally agree with you. The language has totally jumped the shark and gets worse with every standards release. I have a book that's over 200 pages that goes over how to use move semantics - just move semantics, that's all the book is about. I'm sorry but that's just absurd. I dunno maybe the language is this way so that more books on how to navigate the mess get sold.

  • @child_of_god_
    @child_of_god_2 жыл бұрын

    i find this video hard to understand. a video by "the cherno" named "Move Semantics in C++" really kills it. it's down to earth

  • @shoulderstack5527

    @shoulderstack5527

    2 жыл бұрын

    Yes, The Cherno is brilliant. All his C++ stuff is a god send.

  • @_Omni

    @_Omni

    Жыл бұрын

    Its not hard 🤣

Келесі