Rust and RAII Memory Management - Computerphile

แชร์
ฝัง
  • เผยแพร่เมื่อ 6 มิ.ย. 2024
  • Rust has memory management built in. Ian Knight takes us through some of its features.
    Garbage Collection video: • Garbage Collection (Ma...
    / computerphile
    / computer_phile
    This video was filmed and edited by Sean Riley.
    Computer Science at the University of Nottingham: bit.ly/nottscomputer
    Computerphile is a sister project to Brady Haran's Numberphile. More at www.bradyharan.com

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

  • @cowslaw
    @cowslaw ปีที่แล้ว +618

    Rust’s borrow checker is one of the most powerful and strict features of any language I’ve ever used, and it’s absolutely wonderful!

    • @nicholas1460
      @nicholas1460 ปีที่แล้ว +18

      Let's make a Groovy for Rust so we can ignore all that and turn it into an interpreter.

    • @alucard87
      @alucard87 ปีที่แล้ว +8

      @@nicholas1460 absolutely! Lets bring gstrings everywhere!🎉

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

      @@alucard87 The pervs have surfaced. Anyone has anything to do with the Groovy language is responsible for what they do.

    • @KX36
      @KX36 ปีที่แล้ว +33

      meanwhile, every rust user: "unsafe { ... }"

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

      There's stricter features in Dafny, but I'm not sure those are "absolutely wonderful". They certainly are very interesting though.

  • @refactorear
    @refactorear ปีที่แล้ว +559

    9:19 I would say exactly the opposite, in this situation the best for your program is to crash, the worst is to get garbage and continue as if nothing had happened as it might takes months, years or decades to find out such a problem (especially when dealing with processing data and not knowing the kind of output you should expect). What usually happens, though, is that you get intermittent crashes depending on the memory values you get from that dangling pointer.
    Pretty sure the constructor and destructor in the C++ version needs to have the same name as the class, but that's besides the point of the video.

    • @Fs3i
      @Fs3i ปีที่แล้ว +64

      I was gonna write that. The best case for a UAF is usually a crash, rather than silent data corruption, or revealing random memory. Both of them are security/safety risks, which can undermine everything your program does.

    • @bkucenski
      @bkucenski ปีที่แล้ว +28

      Yep. When things break loudly, it's a big motivation to go fix it. You can also log exactly where the crash happened and the state to track what caused it so you can prevent the problem in the future.

    • @-dubu
      @-dubu ปีที่แล้ว +21

      Fail early and loudly

    • @crateim
      @crateim ปีที่แล้ว +23

      this! crashes are problems that actually got *detected* and *prevented* - crashes are your friends

    • @ClifBratcher
      @ClifBratcher ปีที่แล้ว +13

      💯 The development time (money) involved in debugging the garbage cases is dramatically larger than failing fast.

  • @cno9984
    @cno9984 ปีที่แล้ว +633

    I like how neither his C++ or Rust code snippets would compile.

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

      correct hahaha

    • @KaneYork
      @KaneYork ปีที่แล้ว +145

      The C++ has extra sneaky [Undefined Behavior] too, because he used `delete` instead of `delete[]`.

    • @MS-ib8xu
      @MS-ib8xu ปีที่แล้ว +62

      I was wondering about that... I was thinking "surly they would have caught that, maybe it is a new feature in C++, the constructor can just be called Foo"

    • @leogama3422
      @leogama3422 ปีที่แล้ว +60

      That's what 'pseudocode' means. It's for other fellow humans, not computers...

    • @klittlet
      @klittlet ปีที่แล้ว +13

      Needless to say that is just for the purpose of explanation

  • @barbiefan3874
    @barbiefan3874 ปีที่แล้ว +207

    09:20 - it's pretty much the other way around. Best case - your program crashes, worst - you get wrong data and use it.

    • @256shadesofgrey
      @256shadesofgrey ปีที่แล้ว +14

      Depends on the program, where exactly in the program this problem appears, and how often it does so. For example if the value was storing the color information for a single pixel, and that value is garbage once every 10 million outputs, and all the program does is display images on the screen, I'd rather have that single pixel flicker with random colors once every 5 frames than have the program crash. At least as a user.

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

      @@256shadesofgrey This thinking is what leads to scanners giving you wrong numbers in your tax reports, look up "Xerox randomly changes numbers". The program should crash and make the developer fix it immediately, not try to ignore it forever.

    • @deadok0k
      @deadok0k 3 วันที่ผ่านมา

      @@256shadesofgrey Hehe, fun fact about Undefined Behavior - you just can't assume what would happen when it is triggered.
      As an example: you program might run on the same amazon cloud server as some Radionuclide therapy-software, and UB in your code might trigger some unknown exploit that breaks vm isolation and corrupts command list for RNT device.

  • @anafabula
    @anafabula ปีที่แล้ว +333

    That "bob" variable you tried to use three times doesn't exist.
    And why not show the compiler output? It's very friendly

    • @chuxmyk
      @chuxmyk ปีที่แล้ว +18

      Exactly. I was going to ask this. I kept searching for where it was defined since the argument passed was “b” and none in func_1.

    • @-dubu
      @-dubu ปีที่แล้ว +45

      It’s not a rust tutorial, it’s explaining the idea of a borrow checker which it does fine

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

      Thanks for clarifying, I was thinking if somehow 'bob' and 'b' are the same variables...

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

      @@-dubu Still wary of learning anything from someone who doesn't appear to know what they're doing.

    • @a.modestproposal2038
      @a.modestproposal2038 ปีที่แล้ว +96

      This kind of sloppiness does a real disservice to the channel and the intent of the video. You can't be bothered to COMPILE all your examples? Or at least "*" annotate the errors in the video? Such obvious errors are a disappointing distraction that pollutes the message.

  • @FF_Fanatic
    @FF_Fanatic ปีที่แล้ว +200

    It seems a little apples-to-oranges to have a raw pointer in C++, but have a vector in Rust. Both of the languages have a suitable vector type that uses low-level operations under the hood and packages that up into a nice-to-use type with the hard work done for you. Using the video's examples for the two languages makes it easy for people who aren't familiar with them to walk away with a very incorrect view of C++ that remains pervasive in the field, but doesn't reflect how ordinary code is written at all. The Rust comparison should come in at the point where it starts to offer more guarantees and functionality than what C++ can offer, and point out that it's part of the language rather than static analysis.
    Even moving (which C++ has too, just different) isn't so much about one owner for something like a vector (the vector already represents a single owner of its memory) as it is about not needlessly copying the vector. Either way works, but one makes copies explicit. There are other contexts where it's more about a single owner for a resource. Borrow checking and trying to use something after it's been moved from are where Rust really starts to bring more to the table in this regard than static analysis with accompanying rules on how to write code so the analyzer can reasonably work with it.

    • @claytorpedo
      @claytorpedo ปีที่แล้ว +41

      This is the same problem I have with most Rust vs C++ comparisons -- you get someone who appears to have virtually no knowledge of C++ that isn't at least two if not three decades out of date confidently saying why their insanely contrived example that no real person would ever do could be better in Rust. I strongly suspect there are things that _would_ be nicer for me in Rust, but instead I just keep seeing crappy Rust salespeople that don't know any C++ but try to pretend that they do.
      This person doesn't even seem to know how the very basic fundamentals like how constructors and new/delete works (this feels too extreme to be live-demonstration nerves, and insane they didn't doctor it in post), so I'm very doubtful they ever knew anything about C++ at all.
      From what I understand, most of what Rust brings to the table is advanced static analysis, which is great, but C++ has a decent amount of that too (e.g. use-after-move or use-after-free).

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

      Yeah, happens a lot. I find a lot of Rust programmers are super into it, espousing all of it's pros, why everyone should use it and usually comparing it to C++. There's also an element of functional vs object-oriented where they all espouse functional or functional-style programming to be *always* superior to OOP despite the fact that OOP is still one of the most common programming paradigms in the world. They all seem to be drinking for the same fountain that says "this is why Rust is better than C++", but don't actually know anything about C++ beyond the base language and usually the 98 standard.
      Rust is kind of a cult and those who love it think every other language is terrible, especially C++.
      Personally, I love Python and C++, but I'll use whatever suits the task best.

    • @bruhe_moment
      @bruhe_moment ปีที่แล้ว +31

      ​@@claytorpedothe advantage of rust isn't that it *offers* static analysis, it's that it *forces* static analysis by default.
      Someone who knows very little C++ is very likely to make this sort of mistake without knowing how it could've been prevented.
      Someone who knows very little Rust won't make this mistake because the compiler defaults don't allow for it.

    • @trapfethen
      @trapfethen ปีที่แล้ว +45

      The video is not demonstrating the Best Practices of both languages and how THEY differ. It is demonstrating the MINIMUMS of the language and how they differ. You can constrain C++ to get much of the same benefits as rust, with the added boilerplate, static analysis configurations, and code-style enforcement that comes with that. Even with all those things, it is still POSSIBLE to create these kinds of bugs because the language allows these unsafe operations BY DEFAULT and won't warn or flag that you are doing something that may cause issues. In rust, if you wish to do these types of operations for the few valid use-cases where they are unavoidable, you HAVE to tag that block as unsafe. In the event of a crash, that is going to be the FIRST place you look.

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

      @@trapfethen Thank you for providing a balanced analysis.

  • @LuizDahoraavida
    @LuizDahoraavida ปีที่แล้ว +262

    5:50 in C++ you need to tell the compiler if what you're deleting is an array with delete[] instead of delete. In that example the memory won't have been freed properly.

    • @LuizDahoraavida
      @LuizDahoraavida ปีที่แล้ว +124

      I guess this just goes for show on how easily memory leaks can happen when the programmer is responsible for the memory management.

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

      @@LuizDahoraavida Just use std::vector.

    • @seth3129
      @seth3129 ปีที่แล้ว +33

      @@LuizDahoraavida now you're getting it :) this is why rust was created in the first place: to eliminated a whole class of bugs caused by common and easy to make mistakes

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

      I just hope that wasn't on purpose

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

      @@seth3129 std::vector already existed from the beginning.

  • @kadlubom
    @kadlubom ปีที่แล้ว +80

    Shouldn't the constructor be 'Bob' not 'Foo' though?

    • @Faladrin
      @Faladrin ปีที่แล้ว +9

      I've not coded in C/C++ for a long time and I was having an aneurism when I saw that and wasn't sure if the code was wrong or my memory. Thanks for the comment letting me know I was right!

    • @Am6-9
      @Am6-9 ปีที่แล้ว +5

      I think its the other way round, the Class should be called Foo, not Bob…😊

    • @alcoholrelated4529
      @alcoholrelated4529 ปีที่แล้ว +8

      @@Am6-9 yeah, Bob should be called Robert

  • @deconline1320
    @deconline1320 ปีที่แล้ว +200

    Even though the goal here was to demonstrate Rust RAII mechanism, it's worth mentioning that modern C++ provides equivalent concepts using unique_ptr and moves. Nowadays, you rarely need to delete memory manually in C++.

    • @bertiesmith3021
      @bertiesmith3021 ปีที่แล้ว +60

      You can still get dangling references pretty easily. Rust solves this with lifetime analysis. This can often be picked up in c++ through static analysis but Rust guarantees that dangling references won’t compile. The c++ is very poorly constructed - just accessing the data() function of std::vector would have been a better example to construct a dangling reference.

    • @TheJaguar1983
      @TheJaguar1983 ปีที่แล้ว +48

      It's the usual Cult of Rust propaganda: Rust is the best, everything else is bad, especially C++

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

      @@TheJaguar1983 C++ Stockholm syndrome in action

    • @TheJaguar1983
      @TheJaguar1983 ปีที่แล้ว +15

      @@slyfox3333 Typical one-eyed Rust fanaticism.

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

      @@TheJaguar1983 cope

  • @br3adina7or
    @br3adina7or ปีที่แล้ว +253

    The reason you can't borrow mutably and immutably at the same time isn't because one function is expecting the data to be unchanging while another is expecting it to be mutable. If that was the case, as you are presenting, multiple mutable references would be allowed at the same time, when they very much aren't. Mutable references are meant to be exclusive so there's only ever one point of mutation for a given piece of data (and no immutable references at the same time), which is done in order to avoid data races and the such. This is why mutable references are often called exclusive references and immutable references are often called shared references. This principle is also applicable to `Rc`, which was mentioned. Rc basically gives shared references to the data, but it cannot be mutable; to have shared mutable data, one would have to use one of the interior mutability data structures (in the case of an `Rc`, you'd probably want a `RefCell`).
    I think it's important to make this clear when introducing the topic of references in Rust, because one of the core design principles is "fearless concurrency", and as such that is baked into its fundamental ownership principles. That is to say, these concepts are inherently tied in Rust. I don't know if this was an intentional simplification, but it's something that shouldn't've been omitted imo.
    As an aside, `Rc` and `Arc` aren't really like garbage collection. Like, they can be used like garbage collection, but basically instead of having a garbage collector go through the memory and seeing what should be dropped, `Rc` and `Arc` keep an internal counter and then increment it when cloned and decrement it when dropped. When an `Rc`/`Arc` is dropped and there's no more references, it just drops the underlying data. This means that using these smart pointers has a slightly different cost to the equivalent code in a garbage collected language. (Though this isn't really a major point.)

    • @valcron-1000
      @valcron-1000 ปีที่แล้ว +21

      GC is not just mark and sweep. Reference counting is a form of garbage collection

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

      I was going to post the same comment but you worded it better than I could have 😅

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

      also having multiple mutable references might cause data to become invalid. imagine taking a eference to the first item in a vector, and then overtiting the vector with an empty one. now our reference points to unitialized memory

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

      Basically you pretended to "fix" something the video doesn't say in the first place, and failed to do so. I am used to this pointless pedantry on StackOverflow: not ready to face it here on YT, frankly.

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

      @@valcron-1000 I think the term GC is often misused that way, but I don't think it's correct. Python, for example, has a garbage collector, but it also has ref counts, and the GC is only there to clean up things the ref counting can't handle fully (like cycles). You can't have garbage collection without a garbage collector, and Rust definitely doesn't have one (any more).

  • @FPSMinecraftable
    @FPSMinecraftable ปีที่แล้ว +121

    Shouldn't constructors in C++ have the same name as the class?

    • @Hexalyse
      @Hexalyse ปีที่แล้ว +74

      If this was the only error in this video. Most variable and parameters names were wrong in the Rust example (n becoming bob, b, becoming bob, etc.). I liked the video but it was a mess. Trying to compile the code to show what it does would have allowed to detect those problems.

    • @AlFredo-sx2yy
      @AlFredo-sx2yy ปีที่แล้ว +36

      @@Hexalyse also delete instead of delete[], among other things, filling this video with tons upon tons worth of UB.

    • @Finkelfunk
      @Finkelfunk ปีที่แล้ว +13

      @@Hexalyse That is the issue with academic CS though. They are more interested in concepts and less in being code monkeys. They can design the most complex ideas and constructions, but in the end the people that work with the language on a daily basis will know a language better than they do.

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

      @@Hexalyse It seems to me like all, or nearly all of these errors would have been caught if he just tried to compile his code after each demonstration. And actually *demonstrate.*
      But to be fair, he seemed a bit nervous in front of the camera and I don't blame him for getting lost. Next video will be better, I'm sure of it :)

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

      @@Hexalyse Explaining and coding at the same time is not the best option for everyone I guess! 😆😁
      Probably it would have been a better idea to first write and test all code first before showing it in a presentation.
      Explanation was fine though.

  • @tropicbliss1198
    @tropicbliss1198 ปีที่แล้ว +70

    It’s worth noting that rust has type inference, so you don’t have to specify your type every declaration of a variable

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

      @MenaceInc Well it would be a shame if it doesn’t 😂

    • @NuclearCraftMod
      @NuclearCraftMod ปีที่แล้ว +27

      @MenaceInc While you’re correct, C++‘s type inference, which is similar to Java’s, C#’s, etc. isn’t _quite_ as powerful as Rust’s, which is more like those found in functional-first languages. For example, in C++, you can’t write something like “auto x;”, while “let x;” is valid in Rust (provided the type of x actually can be uniquely inferred by how it’s used).

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

      If you have rust-analyzer installed you also get phantom type hints inline with your code which makes it so nice to read. No need to hover over variables to see the type like other languages. This seems small but it's so nice.

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

      @@NuclearCraftMod That is not a problem of language but of compiler standards.

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

      @@konga8165 Many of the popular languages's LSPs have that kind of functionality though..? It's just returning more information to the editor following the LSP standard.

  • @GingerGames
    @GingerGames ปีที่แล้ว +62

    This video conflates RAII and ownership semantics quite a bit. This is a common misconception but if this is meant to be an introduction to either concept, this will most definitely confuse a newcomer to these concepts. You can explain Ownership Semantics without ever referring to RAII whatsoever and vice versa. Ownership semantics can be used to aid with a few issues that RAII in C++ causes (such as over use of copy constructors) but they solve different orthogonal problems entirely.
    C++11 onwards also has all of these ownership semantics (rvalue references, std::move, std::forward, etc), but they are an opt-in thing rather than something that is required like in Rust.
    Also, if you are wanting to reduce resource usage as much as possible, RAII is not the right tool for you and will most likely cause you to waste more memory than other approaches.

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

      How does RAII cause you to waste more memory?

    • @zsomborhollay930
      @zsomborhollay930 ปีที่แล้ว +8

      RAII don't waste any resource, it's just a method to handle object states.

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

      I'm not sure I agree at all. This video isn't confusing RAII and ownership semantics at all, but is illustrating how RAII must be handled and enforced for it to work properly. To allow RAII to work at all, the borrow checker/ownership semantics have to be enforced.
      How is this conflating RAII and ownership semantics?
      I'm also unsure how RAII is "wasting memory" to be honest. Rust automatically drops things that go out of scope, but you can also drop things at any point.

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

      @@noahhounshel104 ​ @kwanarchive ​ @Zsombor Hollay
      RAII on its own does not necessarily waste memory compared to other approaches, however the general culture assumes RAII means you should allocate singular things instead of thinking about your allocation separately from your single objects. As a result, a lot of memory is wasted because you off-load the allocation aspect to the single object, whereas RAII could still be useful if you did not do this.
      Another issue with C++ specifically is that they conflate construction/destruction with allocation/deallocation. It is extremely useful to want to allocate an object and then construct it at a later time, destruct it and then deallocate it at a later date, but due to the way C++ has been designed and the culture around C++, most people couple them together (making things bad). Constructors and destructors also do not "return a value" meaning that the only way you can signal something may have gone wrong is by throwing an exception (which might be a huge issue depending on the problem space). This is why many people will just use explicit `init` and `destroy` functions/methods instead of relying on the ctors/dtors, thus bypassing many of the features of RAII.
      I can give you loads of real world examples of codebases that use RAII heavily that are extremely wasteful of memory (compared to other approaches). And to clarify, RAII is not inherently wasteful but the culture around it and how it the languages that have tend to be designed nudge you to use it in such a way that is extremely uncaring about memory allocations by making them hidden.

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

      ​@@GingerGames Eeehhhh. I suppose you can view RAII as "wasteful" if you are never deferring the creation of the objects to a later date, but in the Rust world doing so would just be an Option which is useful/important for a whole host of reasons besides having deferred allocation.

  • @mihir2012
    @mihir2012 ปีที่แล้ว +99

    I think this was explained quite poorly. You can write as much garbage code in any language you want, including rust. What matters is that when you try to compile the code, the rust compiler rejects much more (memory related) garbage than the c/c++ compiler does. Whereas c/c++ will allow you to get to runtime and may or may not crash then, rust doesn't allow you to get to runtime at all until you have fixed these issues. And not once you showed any compiler output at all. Which is also probably why you kept using variables that don't exist at all.

    • @sobanya_228
      @sobanya_228 ปีที่แล้ว +8

      Rust is like switching to a properly strictly typed language after coding in some poorly typed codebase in a gradually typed language.

  • @fllthdcrb
    @fllthdcrb ปีที่แล้ว +17

    21:01 You also can't have a mutable reference to an immutable variable, which Ian had at this point. And regarding mutable and immutable references, it's not just that you can't have both of those, you can't have _any_ other references, mutable or immutable, if one of them is mutable, for similar reasons. (It's a little more subtle, though. For these purposes, Rust only cares about the span of execution when the variable is actually used. That's why the example with moving an object from one variable to another is fine, because after that the first variable isn't used. In the same way, you can declare and use multiple mutable references to the same object in the same scope, as long as the regions where they're used don't overlap.)

  • @zamf
    @zamf ปีที่แล้ว +14

    What wasn't mentioned is that the C++'s standard library is build around RAII and the notion of moving data around, so the concept is not new for Rust. Rust just enforces it by the compiler, while C++ lets you use RAII as well as unsafe resource management.

    • @TheJaguar1983
      @TheJaguar1983 ปีที่แล้ว +9

      Rust programmers tend to not know that because they're too busy running down other languages' flaws

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

    6:32. RAII doesn't put allocation/deallocation as work on the programmer. The programmer can use STL containers and pretty much never use the keyword new. It is called rule of 0 and is the core essence of modern C++.

  • @germandkdev
    @germandkdev ปีที่แล้ว +81

    Thank you for this explanation of RAII, it was really interesting. But nearly all examples shown wouldn't run as either variables or methods are wrongly named. (Foo constructor in Bob, bob instead of b in all rust functions)

  • @myronkipa2530
    @myronkipa2530 ปีที่แล้ว +46

    Some of the things Rust does the right way:
    1. RAII or memory ownership model - follow few rules and forget about memory leaks
    2. Traits composition instead of trait inheritance.
    3. Powerful enums/unions - can hold values. You have to consider all cases
    4. Pattern matching
    5. No NULL. Instead - enum with optional value
    6. Powerful macros
    My main complaint with rust is that compiler won't let me be silly and write bad code. This also means it won't let you shoot yourself in the foot. But the learning curve is a bit steep. Rust is so different from other languages

    • @ifcoltransg2
      @ifcoltransg2 ปีที่แล้ว +9

      Rust is inconvenient to prototype things in. That's probably why we see a lot of Rust rewrites of existing programs, that already got prototyped decades ago.

    • @0x5DA
      @0x5DA ปีที่แล้ว +8

      @@ifcoltransg2 for some stuff. though, i actually find myself specifically leaning to rust to prototype in, because the way one lays state out makes it a lot easier to understand how the program would work, for me

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

      @@0x5DA I did overgeneralise. I guess Rust's type system is great when you want to make sure things end up correct and well structured. It gives you some support there to create a solid foundation. But I do find, for the kind of project you just want to get working, it's easiest to throw up some Python onto the screen first, rewrite it in a type system after.

    • @0x5DA
      @0x5DA ปีที่แล้ว

      @@ifcoltransg2 i get that, for making it work! no worries

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

      ​@@ifcoltransg2 After using rust for personal projects and then nearly a year in production, I now find it much easier to prototype complex ideas in.
      The biggest help it provides is in easily helping you design your data model in a way that your program can never reach an invalid state (mostly thanks to the absence of null or similar and the conciseness of enum variants).
      Nowadays when prototyping something I usually go to Rust first because I know that if there's a lib to do what I want it'll 9 times out of 10 (if not more) have standardized, easy to navigate documentation and the auto-completions brought about by the strict type system will guide me through the process.
      I do agree with the OP on that it takes quite a bit of time to learn and even more to become actually proficient in it (not even mastering it, just being able to "realistically" pick Rust for a time-sensitive project); I wouldn't ever recommend it to someone as a first programming language.

  • @irlshrek
    @irlshrek ปีที่แล้ว +9

    awesome video! there are so many interesting things in rust! hopefully we get more Rust content

  • @FalcoGer
    @FalcoGer ปีที่แล้ว +35

    Your constructor and destructor for class Bob should be Bob and ~Bob, and not Foo and ~Foo.
    If you allocate an array with new, you need to use delete[] to clean that up, not just delete.
    In your rust code, you refer to bob when you variables are named n and b. Maybe you should get an IDE that highlights errors for you. Vim is great and all, just use syntastic or some other plugin to do that for you.
    Bare pointers are fine so long as it's simple and easy and there is no chance of accessing memory after it has been freed or it being very unlikely that you forget something. You should just use smart pointers instead otherwise. Unfortunately something that starts out simple can quickly grow in complexity and if you are not careful designing your API to your bob instances, someone might pull a pointer and use it outside some scope. Instead of trying to remember to allocate and clean up in two different spaces, you should just let the smart pointers handle that for you. They are well optimized. They do of course have their own drawbacks like cyclic dependencies that need to be watched out for, but generally they are the better choice.
    In your Bob example, a unique pointer would simply not work as you can't copy it without handing over ownership, and a shared pointer would work just fine, although you still wouldn't want to just return it like that as n probably makes no sense without bob. A weak pointer is probably the right choice here.
    If you want a fair comparison, then bob in c++ would also hold onto a high level structure, like std::vector, instead of a bare int[].

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

      Err, no, an array of int would be represented by int*.
      int *x = new int; // fine
      int *y = new int[5]; // also fine
      delete x; // correct delete for single item
      delete [] y; // correct delete for array
      int ** would be an array of array of ints or a way to pass an array by reference in a C-style function so that you could (re)allocate it.
      But you are right about the rest, std::vector is almost always preferred if you need a dynamic array, or std::array if you don't.

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

      @@oracleoftroy fixed it. you are correct.

  • @h-0058
    @h-0058 ปีที่แล้ว +44

    Nice video, the Rust borrow checker is pretty cool, but the C++ comparison didn't make much sense. C++ has had smart pointers for 12 years now (maybe more with boost), which get rid of all the problems except dangling references. You never write new and delete in C++, you never use raw pointers that own memory, you can move or only "borrow". The only thing where standard C++ will not help you is if you borrow a pointer and try to access it after the owning pointer deleted the memory (so dangling references).

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

      Smart pointer still sucks though. Not everyone will use it, and adds complexity. Atleast Rust understands what you're doing and prevent errors before you spend hours debugging.

    •  ปีที่แล้ว +1

      There are a few more things C++ won't help you with but yeah, this was kinda strawman argument.

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

      C++ has had RAII capabilities since the 80's even, it was just made more nicely with the addition of move semantics.

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

      I still use new and delete and never have a problem with it.

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

      @@hanifarroisimukhlis5989 Not true. Smart pointers are excellent. On the other hand, the time you save on debugging with Rust, you waste fighting the borrow checker.

  • @JR-mk6ow
    @JR-mk6ow ปีที่แล้ว +9

    I work as frontend and I've started using Rust because I was missing messing around a low-level language. I'm in love! It's harder than JS (and way slower to build anything) but the borrow checker and the compiler are so so so good.

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

      just use c++ rather than an esoteric language like rust

  • @konga8165
    @konga8165 ปีที่แล้ว +34

    Huge fan of Rust. I've been writing it in production for over a year now and it's been a dream to work with.

  • @Speglritz
    @Speglritz ปีที่แล้ว +49

    Great video. One remark would be to try compiling your examples next time. I think people unused to these languages could become confused when the code isn't accurate.

  • @candysugar5681
    @candysugar5681 ปีที่แล้ว +46

    Why do you intentionally write bad code in C++ to elevate Rust? I'm sure the Rust community doesn't want you doing that.

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

      Right. C++ solves this problem with std::unique_ptr.

    • @kwanarchive
      @kwanarchive ปีที่แล้ว +11

      The code is bad, but it's also more code than necessary. He had to go out of his way to make an issue, whereas one std::vector would have solved the problem.

    • @micahrufsvold
      @micahrufsvold ปีที่แล้ว +9

      I think you're forgetting the audience this video is for. A lot of people watching this don't know about rust, c++, or memory management, and they aren't going to be coding embedded code any time soon. He just needed to demonstrate clearly and quickly the memory management problems that Rust's ownership model is trying to solve. This isn't a sales pitch for programmers, it's educational content for laypeople.

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

      It's really easy for a new programmer that doesn't know about smart pointers to fall for those traps. If he wanted to make that point he probably should had used C.
      Rust is better than C++ for other reasons so you're right, no need to write bad C++

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

      The point is also that you *can* write memory unsafe C++, despite following rules like RAII, whereas you can't in Rust, unless if you write "unsafe" somewhere.
      He could've presented an automatic code analysis tool for C++ that implements the move/borrow semantics and gotten to the same result, but rust has that tool built in and a syntax that is built around the move/borrow semantic, so why not use that instead.

  • @timokreuzer1820
    @timokreuzer1820 ปีที่แล้ว +18

    So Bob has a constructor called Foo? And the scalar delete operator is used in the destructor to delete the array allocated with operatot new[]? And b gets automagically renamed to bob in Rust? I guess we are dealing with a computer scientist here.

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

      Nah, just your average Rust evangelist.😝

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

    Thank you for sharing this excellent video! I truly appreciate the effort put in by education professionals like you to create such valuable content.

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

    So, in the C++ sample you use raw pointers and manual memory management, which is not recommend in modern C++, and you could use std::vector and return it by copy, move or const reference then you'll get the same behavior as in Rust or whatever you can want 🤷
    And don't forget about references in C++ too.
    However, I agree that more control that C++ gives to developer requires a lot more responsibility.

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

    Can you please share the NeoVIM configuration used by Ian in the video?

  • @user-xs2op2iy3w
    @user-xs2op2iy3w ปีที่แล้ว +4

    You absolutely wrong when tell about C++. C++ already has RAII classes in STL, and in most cases you do no need to handcraft memory management.
    Also, resources are not only the memory, as other commentators mentioned, it might be any thing what you get from OS, like: window handles etc.
    The key difference in C++ and Rust is move by default in rust, and borrowing.

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

    Nice to see y'all covering Rust

  • @philosophyze
    @philosophyze ปีที่แล้ว +35

    I've been learning Rust this last year. Love it.

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

    Immutability works much differently in Rust than in TS. In TS, when dealing with non-scalar values such as objects or arrays, a const won't allow the value itself to change (e.g. memory address), but you can still push to an array or add a property to an object. In Rust, it's an effective Object.freeze by default where you still need to declare "mut" to allow modifications to the underlying compound value. This is a very important distinction.

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

      Lack of mut in Rust is much closer to const in another language... C++. When applied directly to an object (like a variable), the meaning is basically the same in both languages (but there is a significant difference when applied to the type of a reference). Whether for the presenter's lack of C++ expertise or another reason, this video makes it look like the difference between C++ and Rust is many times greater than it actually is.

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

    The C++ code is wrong in the video. First off, the constructor name. And also, in C++ if you allocate an array you gotta use delete []. The concepts were explained somewhat vaguely. I recommend anyone trying to learn this, trying to the same stuff you do in C++ just write in Rust, and the compiler will automatically guide you towards the right way to do things. In C++, it will just let you do that stuff, no problem.

  •  ปีที่แล้ว +1

    Cool that you made a video about Rust!

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

    rust newbie here, this is possibly the best introductory explanation to the rust borrow checker i saw on the internet

  • @spark_coder
    @spark_coder 9 หลายเดือนก่อน +2

    This is a very thorough explanation... thank you for that...
    But I must point out that at 5:45 inside the cpp program, within the destructor, the use of the delete keyword (delete this->n) in order to deallocate the array is wrong since it only removes the first element as the array is technically a pointer, therefore you would have to use the delete[] keyword (delete[] this->n) or loop through and delete each element.
    Thank you for this wonderful video ❤

  • @Ceelvain
    @Ceelvain ปีที่แล้ว +14

    RAII must be one of the biggest misnomer in programming. The core of the concept is not to bind resource acquisition to the initialisation of a variable. But rather to bind the resource release with the destruction of a variable.

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

      The core concept is to bind the resource lifetime to a variable lifetime. This includes both binding the resource acquisition to the initialization of a variable and binding the resource release to the destruction of a variable.
      That's why languages without constructors like Rust cannot fully implement RAII as they cannot bind the resource acquisition to the initialization of a variable.
      The resource has to be acquired and then binded to its RAII variable, if stack unwinding happens between the resource acquisition and its binding, the resource won't be released.

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

      ​@@gehngisnot really, when the stack unwounds the resource is dropped/released, unless releasing such cause further exceptions.

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

      @@hanifarroisimukhlis5989 no stack unwinding does not cause resources to be released. It just destructs variables. If a resource isn't held by a RAII variable it won't get magically released.
      Releasing resources can mean anything like making a system call, sending USB data to a device or sending a network packet to a server. Rust, or any language, cannot do that on its own that why we have RAII: to make the system call/send USB data/send network packet in the destructor of a variable which holds the resource.

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

      @@hanifarroisimukhlis5989 I think he meant if an exception occurs between (for instance) a malloc and setting the field RAII-variable. Then we would get a memory leak.
      Which is true, but it would be true of any RAII system. The resource allocation and the binding cannot be made in one atomic step.
      And my point was exactly this. We dont actually really care about the specific details of the steps to acquire a resource. What we care about is that the bulk of the code cannot leave a resource unreleased.
      Also, it doesn't actually matter if the variable initialisation happened miles before the resource is bound to the variable. As long as it is bound ASAP after it's been acquired in order to avoid the case mentioned above.
      Hence, it'd be better called DIRR. Destruction Is Resource Release. Or RRID.
      You know what? Let's try to popularise those names. 😆

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

      ​@@Ceelvain In rust it definitely doesn't matter whether the value is bound or not to whether there is a gap in which a panic (aka exception) can cause a memory leak. There is no gap, when these things are lowered to the low level intermediate language all temporaries have bindings and drop elaboration happens at this level. All possible code paths are covered, including the panicking ones.

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

    2:37 This is NOT the same as in other languages. Val in Kotlin, final in Java, etc. makes the variable itself not reassignable not immutable.
    final var person = Person(19);
    person.setAge(20);
    does mutate the variable even if it has final. In Rust, however, you cannot* mutate the variable at all (as for age_set(u16) you would need a mutable reference).
    (* ignoring concepts like internal mutability using RefCell (assures the 1 mut xor n imut rule at runtime instead of compile time), unsafe and such)

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

    Yay a video on Rust!

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

    5:40 you meant 'delete[] this->n;'
    in C++ there is difference between 'delete' and 'delete[]'.

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

    i’m curious if you could compare garbage collection and rust’s way of doing things with nim’s arc/orc, i’ve heard it doesn’t need to use atomic operations unlike other language’s arc implementations, but i’m not that familiar with how it works under the hood

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

    So long as a mistake can be made, it will be made eventually.
    To me that's one of the greatest strengths of Rust. It prevents you from making common mistakes by being opinionated enough in it's design.

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

    C++ nitpick: you can't have a function ~Foo in a class named Bob. The destructor has to be named ~Bob, and similarly for the constructor.

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

    The "many read-only or one read/write reference" rule is also part of the dangling pointer protection. Imagine you have a Vector with a bunch of elements, and you take a reference to one of those elements. Suppose you were to now extend the vector. In that case, you might exceed the allocated capacity, causing the whole thing to be moved to another place in memory -> your reference to the original vec (which has now been deallocated) is now invalid. Besides that, not allowing two mutable references also prevents data races, which are considered unsound in rust.
    It might also be worth mentioning that memory leaks are not considered unsafe or unsound in rust and are totally possible with safe rust(Box::leak, or having reference counted smart pointers point to each other in a loop like Rc1 -> Rc2 -> Rc1).

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

      The vector case you mention is critical. I’ve had bugs in a C++ program just due to passing a reference to an element on the stack along with a reference to the object containing the vector. Way farther up the callstack that vector grew and the reference on the stack got silently invalidated.
      Because of how complex the code had grown, going back and refactoring to eliminate this ‘unsafe borrowing’ was completely impractical, and the easiest way to fix the bug was just to create and use a new ‘paged’ container instead of a vector to ensure that growing the container would never invalidate references.
      If it had been written in rust from the get-go, that code would have failed to compile early on, long before so many dependencies were written on top of it!

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

    More rust content I love it a lot

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

    That first example, where he was trying to demonstrate the difference between C++ and saying that you have to implement RAII yourself in C++, while Rust does it automatically, is just plain wrong. The authors of the Rust standard library had to manually implement the Vec struct, just like the authors of the vector class in the C++ standard library (which is what he should have been using in his C++ example). That's not a difference between the two languages. The stuff about borrowing is a difference, but that's not related to RAII.

  • @AU-hs6zw
    @AU-hs6zw ปีที่แล้ว

    Thank you!. It is a great video.

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

    We can use this in our stack when implementing javascript webapps or is that not even necessary?

  • @Rick.Fleischer
    @Rick.Fleischer ปีที่แล้ว +2

    In C++, aren't constructors and destructors required to have the same name as the class?

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

    I think something that was a little left out ist that you can do most things with rusts RAII principles (except for multiple owners, so reference counting). If you want to free some memory halfway through an objects lifetime, you can give the Memory to an `Option` which does runtime checks on the variables validity, which your Object then holds onto. This then forces users of the object to consider whether or not the memory is valid at that current time. In rust you very rarely actually need `unsafe` blocks, unless you're doing something like embedded programming or unsafe magic.
    Also rusts reference counting doesn't actually violate the one owner principal, since the reference counted "backend" owns the original data (in implementation this isn't quite correct, there is an UnsafeCell backing all of this, but for the users purpose this doesn't matter)

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

    great video - thank you

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

    Am i the only one watching this, finding it super interesting every single upload yet understanding about 5% of what they tell u?

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

    Writing C-with-classes and calling it C++ (in that you didn't use std::vector, which is the proper approach to this code) is a bit of a hatchet job. What Rust has "built into the language" is literally right there in C++ just the same.
    I know examples are usually contrived but like damn dude.

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

    1:14 does it need an immutable reference or a mutable reference?

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

    Hi, can you use a tripod please or set the framerate to 24-30FPS(after recording) the high-framerate causing motion issues for me, an is why I don't watch many new shows/movies. It may also be caused slightly by the auto-focusing(type)

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

    how does it handle memory shared between different threads? Just use a ref counter? unsafe block with fine grained control? Anything to make either of these easier?

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

      Generally reference counters in combination with Mutex or RwLock. These encapsulate the value and return a wrapped (Guard) reference when you call lock(). The lock is automatically released when the Guard goes out of scope.
      Channels help with passing data between threads. Rust also tracks what's thread safe and what isn't via the Send and Sync marker traits. Rayon is a nice library where you don't have to deal with that if you just want parallelism for iterators.

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

    Completely unrelated question: why the numbers to the left of the code in the compiler are like that?

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

      The one to the left is line number, the one to the right is distance from the current line. This lets you easily execute editor commands such us ‘go up N lines’ or ‘delete next N lines’.

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

      @@mina86 Oh ok, that makes sense

  • @rretro2042
    @rretro2042 29 วันที่ผ่านมา

    Would using vectors instead of raw arrays in c++ help mitigate the memory leak issue a little more?

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

    I hope they add some touch of dependent types beyond a number in a type

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

    In C++ the constructor/destructor are named after the class. The Rust example seems not equivalent to the C++ one.

  • @adamd0ggg2
    @adamd0ggg2 ปีที่แล้ว +9

    After learning Rust, my best advice is to write it without using borrows at first. Do a lot of copying and returning new objects. It is not efficient but it trained my brain to think about the memory allocation and moving process. Then borrows felt like a natural optimization.

  • @TJ-hs1qm
    @TJ-hs1qm 2 หลายเดือนก่อน

    The explanation was perfectly fine for me, on point. There are millions of other channels to learn about the syntax 👍

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

    Okay, but it's not C++. No one writing programs like that in real life.
    There are tools which will help you to find different kinds of errors.
    Clang-tidy, Valgrind, PVS Studio, compiler flags like `-fsanitize=address`, maybe something for MSVC from Microsoft.
    Clang-tidy, can analyze code in real time, it's easy to use, and built in in CLion IDE, can be easy installed in Vim/Emacs with a help of LSP and clang tools.
    And of course there are unique pointers and move-semantics since 2011. Rust is cool, but C++ does not stand still.

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

    9:20 I would actually say the inverse here: at best the program crashes, at worst it gets some garbage. In my experience, debugging with garbage data has been much more hellish than immediately getting a seg fault and knowing the exact location of the problem.

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

    6:21 - You have an error. You didn't use the right form of delete. You need to delete arrays differently. In this case, it probably will be just fine.
    Also, you keep saying "C" and then using "C++". They're different languages.
    Lastly, the appropriate comparison is not to bare C++ pointers. I hardly ever use those anymore in writing C++ code. The proper comparison is C++'s unique_ptr and shared_ptr. The concept of mutable and non-mutable borrowing doesn't exactly exist with those. But those are the closest equivalent to what Rust is doing.

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

    You should also take a look at Zig.

  • @thebsv
    @thebsv 20 วันที่ผ่านมา

    Amazing, what is luasnip and is it better than rust-analyzer?

  • @Guru4hire
    @Guru4hire ปีที่แล้ว +13

    Wouldn't you just use a unique_ptr in the c++ example and do essentially all the same thing?

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

      unique_ptr is called unique for a reason. He would've had to create a (deep and expensive) copy of the vector to resolve the problem if he used unique_ptr (or vector). The solution would've been shared_ptr, but even that has a runtime cost, whereas in Rust it would've just been a completely free borrow and no unique_ptr / shared_ptr at all.

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

      You can create a std::unique_ptr and move it around to pass ownership or pass it by reference to allow borrowing of it. Its the point of unique_ptr. Its what it does.

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

      @@Guru4hire Yeah but that misses the point of the example in the video. The example was that Bob had ownership and got destroyed and there was a dangling reference to the numbers still. unique_ptr wouldn‘t have helped here at all, unless you would‘ve moved out the numbers, but that‘s not what he wanted to do, he wanted to destruct Bob.

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

      I think I understand the point of disagreement now. I am saying that a unique_ptr to a class or struct bob which has a public unique_ptr to a vector of ints performs essentially the same as all the rust code examples. I would argue that the pathological get_n function (which is not in the rust example) in the c++ example would fail to compile as the unique_ptr's copy constructor is deleted. I would have liked to see how Rust handles the contrived use after free bug with the get_n function.

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

      @@Guru4hire one other thing is that C++ unique and shared is a runtime cost where Rust is a compile time check.
      C++ compiles down to pointers allocations and checks where rust just compiles to pointers.

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

    Rust doesn’t actually prevent memory leaks. It is fully possible to leak memory in safe rust, although a little harder. This is demonstrated by std::mem::forget, which was at one point unsafe, but after a while it became clear that preventing memory leaks entirely was unpractical in a language like rust, due to e.g. reference counting cycles or deadlocks or tons of different things

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

    19:49 where are you getting bob.n from? The value of bob is held in variable name b, not bob. is this just a typo you didn't notice?

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

    I don't know any rust. Isnt the ownership principle the equivalent of using std::move on a unique pointer in c++ only here it's the default pointer behavior?

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

      ownership in rust is quite tightly linked with lifetimes, which (as far as i know?) c++ has no equivalent t

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

      Rust moves are destructive moves, whereas C++ has to leave the moved-from object in a valid state even if it's not used again.

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

      The differences are: Moves are the default, deep copies (called clones) are the explicit alternative. Also moves are "destructive" where the compiler doesn't let you access the variable anymore. In C++ moves put the object into a "valid but unspecified" state, which is a little bit odd for types that don't necessarily have such a concept. Like what's a valid but moved mutex, thread, file, tcp stream, etc? For a lot of types there's an equivalent of a null value, but for those that I mentioned the classes need to do some special "bool is_moved" or so and probably throw an exception on all the methods? It's really weird.

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

      C++ unique_ptr and shared_ptr are just like Box Arc in Rust.

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

    Can someone explain why multiple borrowers of the same data wouldn't be a problem for dangling pointers? If you delete the data, won't references to it become dangerous? Or is the original function still the owner so only it can do the deletion? But how would it know that all the borrowers are done?

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

      Borrowers can't outlive the owner. This is enforced at compile time.

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

    ˇ2:45 : Well, C and Java also have construct to declare something to be a constant. All Rust does is make "constantness" the default, and one has to specify mutability ("variability") using an additional keyword.
    It's not like other languages are like Fortran V on Univac 1100 series under EXEC8, where even integer literals were actually mutable variables passed to subroutines by reference. Now, _that_ was a source of some really nice puzzles for novices.

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

    C++ arrays should be deleted with `delete[]` operator @ 6:04 , this is because over-allocation or an associative array technique is used to hold the number of elements in array, so you need to hint the compiler to de-allocate the latter too.

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

    5:50 Shouldn't it be
    delete[] this->n;
    missing the array.

  • @NaN-se8ye
    @NaN-se8ye ปีที่แล้ว +5

    Class Bob but constructor and destructor Foo?

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

    So, as a programming language and ferry enthusiast, was this interview recorded on the Dover/Calais or Dover/Dunkirk ferry connection? Hope I'll get through it without getting too seasick. 😁. Nah, sorry, that was a bikeshed comment. Very interesting and informative content actually👍

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

    This guy knows neither C++ nor Rust.

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

    5:46 should probably use delete[].

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

    Really nice👍

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

    How does borrowing works in multi threading? Can multiple concurrent functions borrow a variable at same time?

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

      The rules don't change for threading(other then send and sync) If you use scoped threads it's easy to see. You can have either moved ownership, multiple immutable references or one mutable one.

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

    GC is the single worst cause of headaches in my job. I'm a senior programmer who works on video games, and I mostly deal with low level optimizations. An unreal GC collect call is going to cost 125ms on a switch. This is just for a call to GC.Collect, there might not even be any garbage to collect. Yes. that's 10 frames at 60 fps spent just looking for things to free. RAII amortizes these costs so they are hit at the moment they are freed. Spreading it out.

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

    I spotted a mistake in his code. The constructor and destructor should have the same name as the class name. Here name of class is Bob and you named the constructor and destructor as Foo

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

    I thought RAII was different from rusts ownership model.

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

      Those are separate concept which often mesh together.

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

    Hmm? What's the difference between const& in c++ and the borrow "thing" in Rust apart from being more explicit in C++, as where in Rust you have two/several places to signal to the compiler that this reference can't be modified?

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

      Rust & and C++ const & are similar. The biggest difference is lifetimes and borrowing. In Rust we get guarantees we don't in C++. Rust & is non-null, aligned, and guaranteed to be pointing at active memory. It is also guarantees not to have any mutable references also pointing to that data. Rust & can also express lifetimes &'a or &'a static which can be helpful. Another notable difference is that Rust has niches meaning unlike c++ &T is the same size as Option . & can also express thread safety(no data races checked at compile time) unlike C++ &. There are probably a few other things but hopefully that makes sense. Any other questions?

    • @KohuGaly
      @KohuGaly 10 หลายเดือนก่อน +2

      Rust references carry lifetime information. This means, that the compiler can determine where the reference is valid where it isn't.
      For example, consider a "get" function that receives read-only reference to a hashmap, read only reference to key and returns read-only reference to a corresponding value in the hashmap. The key reference was only used for lookup. It's irrelevant after the function returns. But the output is derived from the hashmap reference - it references the same thing.
      There's no way to express this relationship in directly in function signature in C++. You either have to document it or look at the source code to figure it out.
      In Rust, the references have lifetimes, which are part of the function signature. You can express that the output references the same thing as the hashmap reference by giving them the same lifetime parameter, and express that the key is unrelated by giving it a second lifetime parameter. the syntax looks like this:
      fn get(map: &'a Hashmap, key: &'b Key) -> &'a Value {...}
      Now the compiler is able to deduce that this is OK:
      let value = get(&map,&key);
      drop(key);
      use(value);
      and that this is not OK:
      let value = get(&map,&key);
      drop(map);
      use(value); // compiler detects use after free error
      The compiler doesn't even need to see the implementation to deduce this. It can deduce it purely from the function signature. Similarly, at the function definition, it is able to check that the implementation matches what the signature is claiming.
      Note, that this is just one example of the sorts of patterns that lifetimes let you express.

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

    When you have a class Bob in C++, the constructor is named Bob(arguments) & the destructor is named ~Bob(). The code shown in the video can't compile.

  • @31redorange08
    @31redorange08 ปีที่แล้ว +1

    9:17 Isn't it the other way around? The crash being the best case because continuing with garbage is very dangerous?

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

    6:00 this is Undefined Behavior btw, you are not allowed to call delete on a pointer allocated using new[]
    Correct way to free it would be delete[] this->n;

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

    Waited for a quite a while to hear "Rust isn't a niche language". Also it has name for it's memory management system - OBRM (Object Based Resource Management)

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

    What's the editor he's using? Counting lines from bottom up

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

      that looks like neovim with relative line numbering

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

    Finally, a video about Rust! Can it become mainstream now?

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

    Class name is Bob and constructor/destructor name is Foo.
    This is something new added to C++ by Ian !!!

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

    8:40 why use ``new``? That kinda goes against the whole RAII thing. Should have had Bob as an automatic object on the stack so that when you leave that scope its destructor is called without you needing to ``delete`` it. In that case, even the dangling pointer may have been avoided.

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

    I've not done any rust yet, why the random :'s in the variable declaration and the ! in the println? they seem unnecessary

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

      Most of the time you won't need to have the `: type` in a variable declaration, it's inferred. The rationale behind the `!` is to warn you that `println` operates on code, not expressions. The `"{}"` literal isn't really a string, it's just a pattern, which at compile time generates the real code for printing.

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

    if you do a new[] please do a delete[]. Even in a so simple example bug has creep in. Furthers proof that most programmers should not write this kind of code themself.

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

      It's pretty basic stuff that any half decent programmer should get right. It bugs me when people blame such things on the language. Like blaming a car for driving the wrong way down a one-way street.

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

    Y u use the wrong deleter? Where are square bracers?

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

    Thanks for the video. It would be nicer, if there were some program runs as well, like the garbage collection video :)

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

    It would be nice if the code actually compiled (C++ class Bob having constructor and destructor named Foo: no) or does what we're told it is supposed to do ( in rust Vec::new() doesn't allocate anything. It creates an empty vec - such a vec starts allocating in push).