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

แชร์
ฝัง
  • เผยแพร่เมื่อ 12 ก.ย. 2024

ความคิดเห็น • 80

  • @norikazuoshiro6324
    @norikazuoshiro6324 4 ปีที่แล้ว +132

    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 4 ปีที่แล้ว +18

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

    • @masheroz
      @masheroz 2 ปีที่แล้ว

      This one? th-cam.com/video/7Qgd9B1KuMQ/w-d-xo.html

    • @atib1980
      @atib1980 2 ปีที่แล้ว +2

      @@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 🙏

  • @sky_is_the_limit_13
    @sky_is_the_limit_13 หลายเดือนก่อน +1

    He is truly a legend and one of my role models in the C++ world! Thanks CppCon for 'back to basics' idea and for uploading videos here for free!

  • @mathymathhandle
    @mathymathhandle 2 ปีที่แล้ว +6

    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
    @Gloryisfood 2 ปีที่แล้ว +8

    Best move semantics video I've ever seen!

  • @bodguy1035
    @bodguy1035 4 ปีที่แล้ว +10

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

  • @sushillakra21
    @sushillakra21 2 ปีที่แล้ว +5

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

    • @CppCon
      @CppCon  2 ปีที่แล้ว +3

      Great to hear!

  • @codefool3022
    @codefool3022 4 ปีที่แล้ว +6

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

  • @Vermilicious
    @Vermilicious 4 ปีที่แล้ว +12

    Another reason to avoid raw pointers? I think so.

  • @Quuxplusone
    @Quuxplusone 4 ปีที่แล้ว +5

    Part 2 is here: th-cam.com/video/pIzaZbKUw2s/w-d-xo.html

  • @ivancheburan2209
    @ivancheburan2209 ปีที่แล้ว +2

    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
    @Stierguy1 5 ปีที่แล้ว +20

    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 ปีที่แล้ว +1

      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?

  • @pmcgee003
    @pmcgee003 5 ปีที่แล้ว +56

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

    • @francescocapano6732
      @francescocapano6732 5 ปีที่แล้ว +19

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

    • @CookiePepper
      @CookiePepper 3 ปีที่แล้ว

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

    • @Evan490BC
      @Evan490BC 3 ปีที่แล้ว

      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.

  • @joesilver75
    @joesilver75 4 ปีที่แล้ว +3

    Thank you for using the uniform initialization.

    • @joesilver75
      @joesilver75 4 ปีที่แล้ว

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

  • @sezerbaglan1804
    @sezerbaglan1804 4 ปีที่แล้ว +2

    The best explanation ever!

  • @tourdesource
    @tourdesource ปีที่แล้ว +2

    [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.

  • @christoj
    @christoj ปีที่แล้ว

    Thank you, excellent talk, very easy to understand.

  • @bobbymah2682
    @bobbymah2682 4 ปีที่แล้ว +1

    Great talk! Cleared up details for me, thanks

  • @GeorgeTsiros
    @GeorgeTsiros 5 ปีที่แล้ว +3

    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 ปีที่แล้ว +2

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

  • @RaymondHulha
    @RaymondHulha 5 ปีที่แล้ว +2

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

  • @marcospatton
    @marcospatton 2 ปีที่แล้ว

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

  • @dechencheng8847
    @dechencheng8847 3 ปีที่แล้ว +1

    excellent talk!

  • @pedantic79
    @pedantic79 4 ปีที่แล้ว +3

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

  • @kpopisthebestful
    @kpopisthebestful 4 ปีที่แล้ว +1

    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?

  • @thestarinthesky_
    @thestarinthesky_ หลายเดือนก่อน

    @19:23 does anyone know what he meant when he said "as soon as you leave out any reference, it would be the copy constructor or the copy assignment operator"?

  • @manuelvalencia6705
    @manuelvalencia6705 11 หลายเดือนก่อน

    illuminating

  • @HelloMisraji
    @HelloMisraji 2 ปีที่แล้ว +2

    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 ปีที่แล้ว +1

      @@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.

  • @pralaypatoria1352
    @pralaypatoria1352 2 ปีที่แล้ว

    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?

  • @liveonphoenix5045
    @liveonphoenix5045 2 ปีที่แล้ว

    @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?

  • @SuhailKhan-vr6ik
    @SuhailKhan-vr6ik 4 ปีที่แล้ว

    Excellent talk!

  • @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).

  • @liveonphoenix5045
    @liveonphoenix5045 2 ปีที่แล้ว +1

    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 ปีที่แล้ว +5

      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.

  • @lwrcica5
    @lwrcica5 4 ปีที่แล้ว

    Great presentation!

  • @saichandu8178
    @saichandu8178 ปีที่แล้ว

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

  • @player-eric
    @player-eric ปีที่แล้ว

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

  • @fredrikorderud
    @fredrikorderud 5 ปีที่แล้ว +4

    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 5 ปีที่แล้ว +8

      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 5 ปีที่แล้ว +1

      @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 5 ปีที่แล้ว +1

      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.

  • @rahuldeshmukhpatil
    @rahuldeshmukhpatil 3 ปีที่แล้ว

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

  • @sureshm8289
    @sureshm8289 4 ปีที่แล้ว

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

  • @movaxbx656
    @movaxbx656 2 ปีที่แล้ว

    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.

  • @hubertbonnisseur-de-la-bat4858
    @hubertbonnisseur-de-la-bat4858 ปีที่แล้ว

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

  • @Webfra14
    @Webfra14 5 ปีที่แล้ว +1

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

    • @ALX112358
      @ALX112358 5 ปีที่แล้ว +7

      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.

  • @Lecker9419
    @Lecker9419 3 ปีที่แล้ว

    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.

  • @raymondyoo5461
    @raymondyoo5461 4 ปีที่แล้ว

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

    • @dennisrkb
      @dennisrkb 4 ปีที่แล้ว +2

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

  • @Dante3085
    @Dante3085 4 ปีที่แล้ว

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

    • @dennisrkb
      @dennisrkb 4 ปีที่แล้ว

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

    • @MUCplusplus
      @MUCplusplus 4 ปีที่แล้ว

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

  • @jamessilva8331
    @jamessilva8331 4 ปีที่แล้ว

    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_erimez 4 ปีที่แล้ว +22

    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 4 ปีที่แล้ว +5

      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 ปีที่แล้ว +3

      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 10 หลายเดือนก่อน +1

      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 8 หลายเดือนก่อน

      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_ 3 ปีที่แล้ว +1

    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 🤣