Announcement

Collapse
No announcement yet.

The Latest Progress On Rust For The Linux Kernel

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #81
    Originally posted by cl333r View Post
    Then stop breathing air, because air is dangerous it can transmit viruses, stop driving cars - they can crash, stop flying airplanes, stop eating, etc, did you get it already?
    Sure, I wanted to point out: there are stupid analogies for everything.


    Comment


    • #82
      Originally posted by cl333r View Post

      The borrow checker is a concept whose job is to enforce the borrowing rules, which can be checked at compile or runtime. Period.
      Borrow rules need to be enforced in rust. The compile-time borrowchecker does that. But there are opt-in library features which give you temporary mutable access to an object in a single-threaded context. That's the RefCell.

      Comment


      • #83
        Originally posted by cl333r View Post
        You didn't understand: one single function calls borrow_mut() onto the same instance of a RefCell object, let's call this function SuckMuhBalls(), but different callers into SuckMuhBalls() might call SuckMuhBalls() while said RefCell object is already borrowed or not, depending on this SuckMuhBalls() might succeed or crash the app. Hence the problem: how do you know all possible runtime function call paths into SuckMuhBalls() to make sure it never crashes the app?
        There are two issues here. First, SuckMuhBalls(), SuckEmAgain() and DontStop() can all reference the same RefCell just like they could have non-const pointers to the same object in C or C++. There is absolutely no problem with that. The difference between Rust and C/C++ is that in Rust, to be able to actually perform a mutating operation, you must borrow() or try_borrow() it first, which is basically a way to saying to the others "I'm about to mutate the object, you can't do it yourself until I'm done".

        So in other words, when you have multiple potentially mutable aliases, in Rust the attempt to perform concurrent mutations that would yield an undefined result is caught. In C/C++ the problem of course exists exactly in the same way (there is no magic involved), except that it's not explicitly caught and instead corrupts the app with various and unpredictable consequences. Ultimately RefCell is nothing more or less than a mutex of sorts. You are not seriously saying that mutexes are evil, are you?

        Secondly, of course there is a tests coverage problem. That's hard in any language and Rust is no different, but all the same, it's easier in Rust than in say C, precisely because in Rust the behaviour is deterministic. Also, as mentioned, in difficult cases you should use try_borrow() where the type system will force you to really handle the case when you can't borrow the object. C/C++ has no equivalent at all for that. In a broader sense, the C way of signalling a failure is to return NULL or -1, which of course no-one really checks for. How often have you seen C code like:

        int *a = malloc(1000);
        if (a==NULL) { do_something_sensible_to_handle_it(); }

        Comment


        • #84
          Originally posted by oleid View Post

          The funny thing about a RefCell is: you rarely use it at all.
          Meaningless as "rare" or "often" is subjective. I say I used it often because I wrote a C++ like app, not a C like app.


          Originally posted by oleid View Post
          If what you describe would happen in your code, then your callstack would be severely broken anyeay, as the mutable acess is released if access goes out-of-scope.
          As so often told to rust fanboys: aliased mutability != bug && aliased mutability != your fantasies.

          Comment


          • #85
            Originally posted by oleid View Post

            The funny thing about a RefCell is: you rarely use it at all. And in a multithreaded context, the compiler prevents its usage. If what you describe would happen in your code, then your callstack would be severely broken anyeay, as the mutable acess is released if access goes out-of-scope.
            Exactly, this is a really weird contrived example because in a multithreaded context you would use something like a Mutex and not RefCell (because you can't)

            Comment


            • #86
              Originally posted by jacob View Post

              There are two issues here. First, SuckMuhBalls(), SuckEmAgain() and DontStop() can all reference the same RefCell just like they could have non-const pointers to the same object in C or C++. There is absolutely no problem with that. The difference between Rust and C/C++ is that in Rust, to be able to actually perform a mutating operation, you must borrow() or try_borrow() it first, which is basically a way to saying to the others "I'm about to mutate the object, you can't do it yourself until I'm done".

              So in other words, when you have multiple potentially mutable aliases, in Rust the attempt to perform concurrent mutations that would yield an undefined result is caught.
              Not concurrent as we're not talking about threads. The mutation would happen sequentially.

              Originally posted by jacob View Post
              In C/C++ the problem of course exists exactly in the same way (there is no magic involved), except that it's not explicitly caught and instead corrupts the app with various and unpredictable consequences. Ultimately RefCell is nothing more or less than a mutex of sorts. You are not seriously saying that mutexes are evil, are you?
              No way dude, mutexes are absolutely legit. Don't mix a single threaded problem with multithreading. RefCell isn't about "concurrent" mutation, merely about aliased mutability which would happen sequentially.

              Originally posted by jacob View Post
              Secondly, of course there is a tests coverage problem. That's hard in any language and Rust is no different, but all the same, it's easier in Rust than in say C, precisely because in Rust the behaviour is deterministic. Also, as mentioned, in difficult cases you should use try_borrow() where the type system will force you to really handle the case when you can't borrow the object. C/C++ has no equivalent at all for that. In a broader sense, the C way of signalling a failure is to return NULL or -1, which of course no-one really checks for. How often have you seen C code like:

              int *a = malloc(1000);
              if (a==NULL) { do_something_sensible_to_handle_it(); }
              try_borrow() is not an option, if I could I wouldn't have used RefCell to begin with!!

              Comment


              • #87
                Originally posted by cl333r View Post
                I say I used it often because I wrote a C++ like app, not a C like app.
                I'm not really sure what you mean.

                As so often told to rust fanboys: aliased mutability != bug && aliased mutability != your fantasies.
                Still, you failed to give a proper example.

                Comment


                • #88
                  Originally posted by cl333r View Post
                  try_borrow() is not an option, if I could I wouldn't have used RefCell to begin with!!
                  Why is it not an option? And maybe you could give us an example from your code where you HAVE to use a RefCell?

                  Comment


                  • #89
                    Originally posted by oleid View Post

                    I'm not really sure what you mean.
                    Oh my..

                    Originally posted by oleid View Post
                    Still, you failed to give a proper example.
                    A "proper" example of what? Aliased mutability that isn't a bug? I already did give a normal example (don't recall if it was for you) I use relatively often: removing items from a vector looping from end to start, item removal happens based on certain criteria of the item.

                    Comment


                    • #90
                      Originally posted by cl333r View Post
                      Not concurrent as we're not talking about threads. The mutation would happen sequentially.
                      Yes we are not talking about threads, which is why this is a concurrency problem as opposed to a parallelism problem.

                      Originally posted by cl333r View Post
                      No way dude, mutexes are absolutely legit. Don't mix a single threaded problem with multithreading. RefCell isn't about "concurrent" mutation, merely about aliased mutability which would happen sequentially.
                      RefCell *is* about concurrent mutation, which you obviously mistake for parallel mutation. It is to concurrency what a mutex is to parallelism. The point being that it is an acknowledgement that a problem exists. Other languages of course have the exact same problem but they simply fail to even recognise it. I really don't see how exactly is that supposed to be better.

                      Originally posted by cl333r View Post
                      try_borrow() is not an option, if I could I wouldn't have used RefCell to begin with!!
                      Then you will be pleased to know that corner or unusual cases aside, you don't have to use it. In all cases where an object can be copied atomically (from a concurrency point of view), you don't have to use RefCell. You would use Cell where no borrowing is needed. This covers things like scalars, small cheap structs and vectors etc, which are basically the same cases where you can be sure that no problem can arise in C.

                      Comment

                      Working...
                      X