Announcement

Collapse
No announcement yet.

Scope-Based Resource Management Infrastructure Merged For Linux 6.5

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

  • #11
    At this point why not just use a subset of C++, at least enough to get destructors first?

    Comment


    • #12
      Originally posted by Weasel View Post
      At this point why not just use a subset of C++, at least enough to get destructors first?
      Based on everything I've heard, it seems like C++ is a bad word in the Linux kernel community. I expect most of them will stop reading any proposal or patch, as soon as they see it.

      Comment


      • #13
        Originally posted by Weasel View Post
        At this point why not just use a subset of C++, at least enough to get destructors first?
        Destructors mean objects. So it would be quite a substantial subset, I guess.

        Comment


        • #14
          Originally posted by lowflyer View Post
          So, C++ is scorned, rust is not understood, therefore we just use a private extension of the language. Great!

          </sarcasm>
          They do understand rust. That's why they only allowed it in in an experimental capacity. Overhead vs C aside, you don't put a language that's still in rapid development in the core bits of the kernel. Rapid development means it is unstable and thus not suitable for key production code.

          Comment


          • #15
            Originally posted by Weasel View Post
            At this point why not just use a subset of C++, at least enough to get destructors first?
            The cleanup gcc extension is a bit different from the C++ destructor: the former is tied to a variable instance, where the latter to a object type.
            In fact it exists the *experimental* C++ std::scope_exit class that it is more similar to the gcc extension.

            Said that, I agree that using a subset of the C++ would be a lot simpler than using a foreign language (like Rust). However I suspect that the developer community fear to quick loose the control of which C++ subset would be allowed.

            A better a path would be extending the C with the Linux kernel community needing, without worrying about the forward C++ compatibility: one of the main problem of the C++ is that it is very difficult to introduce new keyword, because the conflict of a potential type. In C++ the object don't need "class" or "struct" after their definition.
            The C doesn't have this feature and can be extended more easily.

            Comment


            • #16
              Originally posted by coder View Post
              I happen to think destructors and exceptions are two key features making C++ an excellent systems programming language. It's a good call for the kernel to take up at least one of these. Vastly overdue, but better later than never.
              RAII/scope guards are indeed great. Exceptions however is a scourge. I say that as a professional C++ developer. The issue is that they can bubble up from deep within a library, where you have no idea about what type of errors might be thrown (it is very rarely properly documented). This has bit me more than once at work, in a hard real-time program, where you absolutely do not want to crash.

              Exceptions could work if the allowable exceptions were part type signature and the compiler would error if you didn't either catch them or declare them in your own signature. I have a vague memory of seeing some other language that did that (Java? If so, that would be the single good thing to come out of that language).

              And as much as I like rust (it makes you handle errors by returning something similar to a std::variant, but with better ergonomics thanks to match statements and the question mark operator), the error enums get cumbersome there.
              ​​​​

              Comment


              • #17
                Originally posted by kreijack View Post
                The cleanup gcc extension is a bit different from the C++ destructor: the former is tied to a variable instance, where the latter to a object type.
                I thought about mentioning this, but I'm not really sure how consequential it is. At least, not in how they plan to use it. One nice thing about it is that you can use cleanup functions with a simple int, whereas in C++ you'd normally have to define a class or struct that wraps it, and then either go out of your way to access the member or wrap it with custom operators, etc.

                Originally posted by kreijack View Post
                In fact it exists the *experimental* C++ std::scope_exit class that it is more similar to the gcc extension.
                Not only that. Even std::unique_ptr<> allows custom deleter functions, but the downside is that it only works with pointers.

                Originally posted by kreijack View Post
                Said that, I agree that using a subset of the C++ would be a lot simpler than using a foreign language (like Rust). However I suspect that the developer community fear to quick loose the control of which C++ subset would be allowed.
                Agreed. With C++, allowing even a little bit is going to be seen as "the camel's nose under the tent", both by advocates and opponents alike. It won't be the end of the war over using C++ in the kernel, but just the first battle over which features to allow.

                Comment


                • #18
                  Originally posted by Vorpal View Post
                  Exceptions however is a scourge. I say that as a professional C++ developer. The issue is that they can bubble up from deep within a library, where you have no idea about what type of errors might be thrown (it is very rarely properly documented). This has bit me more than once at work, in a hard real-time program, where you absolutely do not want to crash.
                  I'm with you on the challenge, but we diverge on the solution.

                  In my codebases, the standard for using exceptions is that any exception representing a recoverable error must be documented in the API of the function or class throwing it.

                  That shouldn't be a reason not to use them. Rather, it's just another reason to document your APIs.

                  Originally posted by Vorpal View Post
                  Exceptions could work if the allowable exceptions were part type signature and the compiler would error if you didn't either catch them or declare them in your own signature. I have a vague memory of seeing some other language that did that (Java? If so, that would be the single good thing to come out of that language).
                  Other languages (e.g. Python) use exceptions without such compile-time checks. And I'm not aware of them being so controversial in that language.

                  IMO, exceptions and RAII go together like peanut butter and jelly.

                  Comment


                  • #19
                    Originally posted by coder View Post
                    I'm with you on the challenge, but we diverge on the solution.

                    In my codebases, the standard for using exceptions is that any exception representing a recoverable error must be documented in the API of the function or class throwing it.

                    That shouldn't be a reason not to use them. Rather, it's just another reason to document your APIs.
                    You don't have that control over third party code though, and documentation cannot be trusted to be up to date, unless there is a tool checking it.

                    I was looking at some code the other day, that used boost and a few other libraries internally. After about 5 minutes I gave up on figuring out what the complete set of exceptions it could throw were. It could certainly throw std::bad_alloc for example. What about other std errors like std:ut_of_range? No idea. Depends on if the code has any potential bugs.

                    Originally posted by coder View Post
                    Other languages (e.g. Python) use exceptions without such compile-time checks. And I'm not aware of them being so controversial in that language.

                    IMO, exceptions and RAII go together like peanut butter and jelly.
                    I have run into the same issue in Python code for sure, getting random TypeError, KeyError and IndexErrors bubbling up from deep within library code, because some developer only thought about the happy path.

                    Comment


                    • #20
                      Originally posted by Vorpal View Post
                      You don't have that control over third party code though, and documentation cannot be trusted to be up to date, unless there is a tool checking it.
                      If the exceptions aren't documented, then it's a fair bet the API wasn't tested or designed to recover to a known, good state after they occur. In such cases, worrying about catching them is pretty pointless. The main benefit exceptions provide is that if you have occasion to catch-all + log, you can annotate the error with additional contextual information that can help diagnose the error.

                      Exceptions also support a "log once" policy. It bugs me when one function calls another, which calls another. The leaf function fails and logs, then the middle function sees the failure and also logs it. Finally, the top-level function notices the failure and then it logs. Now, you have 3 different log messages all corresponding to the same underlying error, but you often can't be sure whether they're referring to a singular failure or if some of the latter logs are a consequence of the failure mentioned in the prior ones, or if they refer to independent failures with a common-but-silent root cause.

                      That brings us to another point in favor of exceptions, which is that you can't accidentally ignore them like you can with error codes. Some of the hardest bugs to find are those where an error occurs at one point in time, but symptoms don't present until later. I have yet to see an API using return codes being used without a single omission to properly check-and-handle the return code of every function. As the biggest advocate of exceptions that I know, I'm also fastidious about checking & handling every return code from APIs that don't use exceptions.

                      And, the last argument I'll present for exceptions is that they enable you to centralize your error-handling. It's often possible to structure your code (especially if you use RAII) so that there's one block of error-handling for multiple API calls and you're mostly just looking at the control-flow of your code without the "noise" or "visual overhead" of error-checking around every call making it harder to follow.

                      Originally posted by Vorpal View Post
                      I was looking at some code the other day, that used boost and a few other libraries internally. After about 5 minutes I gave up on figuring out what the complete set of exceptions it could throw were. It could certainly throw std::bad_alloc for example. What about other std errors like std:ut_of_range? No idea. Depends on if the code has any potential bugs.
                      When I need a "last-resort", I typically catch-and-log const std::exception &, as nearly every exception should derive from that and you can use its what() method + typeid() to get details that you can't get when you catch (...).

                      However, it's generally not a good idea to use those catch-all blocks and treat the exceptions you get as recoverable. Unless you have some very good understanding of the code which threw the exception, your best bet is to exit and restart from a clean slate. Otherwise, your program could now be in a bad state and that could give rise to other symptoms which could be mistakenly treated as independent bugs.

                      Originally posted by Vorpal View Post
                      I have run into the same issue in Python code for sure, getting random TypeError, KeyError and IndexErrors bubbling up from deep within library code, because some developer only thought about the happy path.
                      Yup. Generic exceptions, like those, typically indicate a bug in the program. I can't think of a time someone intentionally had an API raise those for expected & recoverable errors.

                      If the developer didn't put thought into making the code exception-safe, it probably isn't. And therefore, you should treat those errors as fatal. If they did put thought into exceptions, they will document them so you know which to catch.
                      Last edited by coder; 06 July 2023, 03:00 AM.

                      Comment

                      Working...
                      X