back to article Sudo-rs make me a sandwich, hold the buffer overflows

Canonical's Ubuntu 25.10 is set to make sudo-rs, a Rust-based rework of the classic sudo utility, the default – part of a push to cut memory-related security bugs and lock down core system components. When it arrives on October 9, 2025, those interacting with Ubuntu Linux software should enjoy a reduced attack surface and …

  1. GNU SedGawk Bronze badge

    Another day, another attempt to force this on us

    If you use simple code, and the STL, C++ is very easy to write correct memory safe code, threadsafe code, portable clean code.

    Lock-Free, Concurrent code, doing fork-join parallelism memory safe, trivial in C++.

    C++ gets better over time, your C code can become C++, can slowly migrate to later standards by deleting code. This example over the years has seen me discard threads(c++11), wrappers(c++20), smart pointers(C++11) the core of this is unchanged from C++98, but the undifferentiated heavy lifting just keeps leaving my code for the standard library, and I'm very happy with that.

    If you use std::array over plain array, from GCC 12+ onwards, you get free SIMD.

    Please show me this in rust and tell me where my opportunities for performance, clarity, portability, memory or thread safety are being neglected and how the Rust code improves on this.

    https://godbolt.org/z/PsMr1xdfd

    1. Jon 37

      Re: Another day, another attempt to force this on us

      Your argument is that a good programmer can write memory-safe code in C++. In theory, you are correct. In practice, there is many years of evidence of memory safety bugs being found in C++ code. And lots of programmers are not good.

      So large programs written in C++ are highly likely to have memory safety bugs. For applications where those bugs are security vulnerabilities, that is not acceptable. The other advantages of C++ are irrelevant if it's impossible to write secure code.

      Any Rust code that does not use the "unsafe" keyword is memory safe. This is enforced by the language and compiler.

      There has been talk of having a memory-safe subset of C++, and making the compiler enforce it. Right now, that does not exist. There is some early development work on how C++ could be extended to allow that. If/when it does exist, then existing libraries will need to be ported to it or wrapped in bindings. It's basically a new language based on C++, with all the work needed to establish a new language - which Rust has already spent years on, so Rust has a big head start.

      1. GNU SedGawk Bronze badge

        Re: Another day, another attempt to force this on us

        Rust is not a serious competitor for C++. It will never compete in that space - ever. It will take margin away from Golang and Python then fall-back into single digits of interest.

        It's not 1980 - you are a thin front-end to a C++ universe, LLVM is written in C++ - so your advantage has corroded before we hit code generation.

        There is nothing that Rust offers over valgrind / asan / ubsan - so essentially you're pretending that a language which lacks any credible examples has an advantage due to checks which are ultimately implemented in a C++ codebase.

        LLVM's entire purpose was to allow people to write custom syntax checks for C++ code as it was more difficult to use the GCC tooling - It's not magic, if you can detected it from the AST then you can warn or even fix it automatically.

        So Rust is not offering anything new, it does offer a great deal of friction and a lot of security issues - It's a tire fire of dependencies, the code is not readable to many people compared to the community of C and C++ literate people. The Compilers are single source, and the people pushing it are utterly untrustworthy.

        So mate, not convinced - C and C++ have known issues, which testing, design, architecture and proficiency render trivial, in return we get clarity, performance, portability, multiple compilers, easy onboarding, continuity of source, an entire global population of developers with decades of experience.

        1. Jon 37

          Re: Another day, another attempt to force this on us

          Rust is fairly new. We don't have the many decades of experience & training with Rust that we have with C++.

          But that argument is basically "we should never do anything new. We should never try new approaches to fix the issues with our current approach".

          When cars came out, we didn't have the centuries of experience with them that we had with horses. There was a big community of people who could use horses but not cars. People understood horses but not cars. The supply chain for the first cars probably included horse drawn wagons. There were a limited number of car suppliers compared to lots of horse breeders and sellers. But ultimately, the advantages of cars meant that, over a period of many years, all that changed.

          But there have also been many other attempts at major changes that haven't worked out.

          It's too soon to know if Rust will succeed or not. Maybe in 50 years a few enthusiasts will be going "remember Rust, shame that didn't take off". Or maybe people will use Rust and look at C/C++ as legacy languages like Fortran and COBOL.

          1. GNU SedGawk Bronze badge

            Re: Another day, another attempt to force this on us

            The argument is that Rust is different in meaningless ways offering nothing new. Reflection in C++26 is new, but functional languages are not new. There is no new idea as yet articulated other than "don't use C++ or C" which is not a new idea.

            It's not an advancement to use a different programming language, it's either an aid or an impediement to the task, but to ditch the C++ ecosystem requires you provide something compelling, Rust doesn't offer it.

            It offers advocacy absent evidence, it's grounded in idealism not measurable advantage. Find a Unicode conversion library in rust which has a sane API and allow you to determine what proportion of the input was successfully converted - https://thephd.dev/the-c-c++-rust-string-text-encoding-api-landscape

            Ultimately ICU written in C++ is the winner. So being in Language X conveys no advantage over experts in the domain doing decent design, which is not new.

            1. FIA Silver badge

              Re: Another day, another attempt to force this on us

              Find a Unicode conversion library in rust which has a sane API and allow you to determine what proportion of the input was successfully converted - https://thephd.dev/the-c-c++-rust-string-text-encoding-api-landscape

              Maybe you could learn it, then help make it better? Nothing is ever perfect from the get go. Or is rust not allowed to evolve decent libraries like C++ has?

              Also... you're criticising a library... not the language at this point... you might as well say C is a shit language because Motif is a clusterfuck, or that Java is shit because of Java.Util.Date....

              I'm a shit coder, so I'm learning rust, as it makes my programs better.

              I'm also old, so have a lot of ingrained 'knowledge' from years of other languages.

              I'm finding learning Rust hard, in a way I've not found with other languages I've used. This is mainly because of my ingrained experience... there are structural norms I gravitate towards that aren't great. It is making me a better programmer though, not just in Rust, but in other languages I use.

              However it is also just a tool, I don't feel threatened by it and I don't understand why we wouldn't try and make things better. (Getting angry at rust is like getting angry at a lawnmower because scythes still exist... it's fine to have both..)

              When I was a young developer I thought C was 'the language' and all other languages were toys, and if you shot yourself in the foot you were just stupid.

              I was wrong; my foot is full of holes.... it's actually nice to have a language that will catch a lot of the stupid mistakes.. because after 30 years of programming I still make them... as do a lot of programmers, because as it's already been said.... most programmers are not very good.*

              However, if you are a good programmer, don't worry, there's enough C and C++ around to keep you in work for the rest of your life, but really don't let new things annoy you, either ignore them or embrace them, don't get angry about things you can't change; you'll get an ulcer.

              * ...or are constrained by work time pressures, are tired, disenfranchised, underpaid; or just make mistakes now and then...

              1. GNU SedGawk Bronze badge

                Re: Another day, another attempt to force this on us

                I'm not annoyed in the least, but perhaps I write poorly and the tone comes across in a manner unsympathetic to my intended means of communication.

                I think Rust itself is poisonous for a few reasons, chief amongst them is the "Trusting Trust" secondly the supply chain.

                I'm happy for people to use whatever they like but it seems incorrect to advocate Rust to help with security without addressing the reproducibility issues.

                I can and do have bit for bit reproducible builds, largely for development speed but also for ease of regression testing. It's not about toys so much as best tool for job.

                Most of the time that is going to be a scripting language (for C language library support), or is dictated by the libraries you want to consume - so there are credible options in Language A, B, C which back on to libXX (written in C) or you have language D which is sort-kinda okay mostly for what we need, but if we ever step out of that subset we're screwed.

                It's not a apples to apples comparison - if you are doing heavy real world kafka - Java or another JVM language is going to help you here as the C library (librdkafka) falls into category D here despite being what you get in ruby/python/php for Kafka support. Golang has a wrapper like everybody else, but also has native clients.

                Rust also uses the C library like everybody else. So big deal, you can call C from your favourite language and still not get any benefit over just using it directly.

                1. FIA Silver badge

                  Re: Another day, another attempt to force this on us

                  I'm not annoyed in the least, but perhaps I write poorly and the tone comes across in a manner unsympathetic to my intended means of communication.

                  Fair... as someone who's often told to stop being so angry (I'm not) I understand. ;)

                  Rust also uses the C library like everybody else. So big deal, you can call C from your favourite language and still not get any benefit over just using it directly.

                  (Assuming you've not compiled without it, yes..) but you're conflating a binary interface with the underlying language. The standard C library doesn't actually have to be written in C, so long as the calling conventions remain consistent.

                  The benefit is in the code I've written, not in the code I'm calling. I shouldn't just abandon writing memory safe code because I may at some point call some assembler that came from a source file written in a language that wasn't.

                  Also, the standard C libary is heavily used, so is well battle tested, but that doesn't mean code that calls it is, or has to be written in C. You seem to be saying that because a part of a thing is written one way then there's zero benefit from attempting to improve the other bits? If I fix the heater in my car I have a better overall experience, even if the engine is still shit.

                  1. GNU SedGawk Bronze badge

                    Re: Another day, another attempt to force this on us

                    I'm saying that the basic idea is flawed.

                    We can have memory safety by having memory safety. Not a property of Rust. We can improve by prioritising improvements to software quality, when you finish laughing reach out to your local QA team.

                    What the reality is that in order to do whatever task we are doing for money, there are credible options, and not credible options.

                    In almost no case is the credible option available for Rust, and not for C++, while the reverse situation as shown with Kafka/ICU is the rule.

                    Then we come to dynamic linking, there is a lot of software deployed in this fashion, and ultimately once you are loading files off of disk and mapping them into memory, you are not going to be any better off in rust or pascal or C or Assembler. You need to get the method signatures correct or dragons will fly out of your nether regions.

                    Rust is not a player in this fight, it can compete for mindshare amongst python developers sick of slow code.

                    You'd honestly have to be crazy to think that the games industry is going to dump C++ or the scientific research community is dumping that code which has been expensively proven correct over centuries of staff effort to gain "Memory safety".

                    That's not important - people want correctness, accuracy, performance, portability, safety is not on the table, nobody cares.

                    There is no security issue that's not already a bug. So it's overblown - you can't leak memory if you don't allocate it. You can't deadlock, if you never acquire a lock.

                    In that example I posted, it's mult-threaded, lock-free, (explicit) allocation free - allocations are happening behind the scenes for the vector - you could make that an array - leaving only the thread itself doing allocations.

                    That's why people like C and C++, its possible to figure out what is going on and why, with a high degree of precision provided you follow some basic rules, 1) either always use the STL or never use the STL.

                    2) RAII

                    3) Warnings are errors, warning on everything you can and test the shit out of your code.

                    1. bazza Silver badge

                      Re: Another day, another attempt to force this on us

                      You can have memory safety in any language you like.

                      The difference between Rust and C++ is that, with C++ someone else has to read your C++ very carefully indeed for them to know that it is completely memory safe, whereas in Rust it's simply a matter of looking to see if "unsafe" has or has not been used. Both can end up "correct", but it's simpler to demonstrate that state has been achieved with Rust.

                      "Suitability for purpose" is as much about the means of achieving an end result as the result itself.

                      1. GNU SedGawk Bronze badge

                        Re: Another day, another attempt to force this on us

                        This is nonsense. Rust adds zero safety to C++. It adds a supply chain risk, and drastically lowers the number of eyeballs available for review.

                        ASAN/UBSAN/Valgrind/SecComp various method exist of verification all of which add more value than `grep -q unsafe || echo "ship it"`

                        1. bazza Silver badge

                          Re: Another day, another attempt to force this on us

                          Hmmm, I think you're over-optimistic about how many eyes are actually available to look at C/C++ code.

                          1. GNU SedGawk Bronze badge

                            Re: Another day, another attempt to force this on us

                            I think that C and C++ constitute orders of magnitude more centuries of accumulated Engineering experience than almost all the other languages combined at this point.

                            If you do serious engineering you use C or C++, everything else is a rounding error.

                            Then take HPC - Fortran is still amazingly widely used, C++ is slowly eating the fields there.

                            Graphics - C++

                            If we don't have enough C++ and C eyes, we don't have enough eyes period - which I don't accept.

          2. bazza Silver badge

            Re: Another day, another attempt to force this on us

            The supply chain for the first cars probably included horse drawn wagons.

            Take a look at this video about the development of the original Shinkansen bullet train in Japan:

            https://youtu.be/iYjFOYLAtoE?feature=shared&t=697

            I've put it at a time point where you can see the first Series 0 power car body being shunted around by a steam train! Talk about big leaps forward. The whole video is pretty good, you get to see some of the hardware for the automatic train control system they built (in 1964!). Not much software involved.

            Ironically, there's some Rust involved.

        2. Anonymous Coward
          Anonymous Coward

          Re: Another day, another attempt to force this on us

          > if you can detected it from the AST then you can

          But what if you can't detect it from the AST (passing pointers, type casting, mmap a file and type-cast memory to a structure)? How about if Rust prohibits the things that can't be represented from the AST, ensuring that you can detect the things that you can do?

          There's been lots of back-and-forth, and potential fixes for C++ to obtain more guaranteed behavior. The rust-cult still exists, and the C++ crowd is still telling us that it *can* be done if we _really want to_ (with standards proposed but not yet, at least, popular). Neither has won the war.

          1. GNU SedGawk Bronze badge

            Re: Another day, another attempt to force this on us

            The bottom line is that stuff is useful, which is why people do it. It's like saying you want to take the sharp knives from my kitchen and make me cook with a spork.

            Sure it might be "safer" but I'm not convinced it's an actual problem compared to say input validation for sql injection or supply chain poisoning which rust makes much easier.

          2. Richard 12 Silver badge

            Re: Another day, another attempt to force this on us

            The main reason people get annoyed is because Rust cannot safely replace C++.

            Several core design concepts of C++ don't exist in Rust. You can fake them, but to do that you wrap the entire codebase in "unsafe".

            In reality, the design of Rust is such that it's only suited to small, monolithic projects that have little to no UI.

            Rust could be very good for replacing small self-contained C utility libraries, and probably for some embedded. But poor to disastrous for anything large, modular, or long-running - and basically impossible for anything with a GUI.

            Though given that the default fault behaviour is to terminate the entire process, and library code must never terminate the process, maybe it's not good for that either.

            1. klh

              Re: Another day, another attempt to force this on us

              Trying to apply C++ ideas to Rust won't work, as evidenced by your last paragraph. Rust doesn't do exceptions, the default behavior isn't to terminate - that's only supposed to happen in case of irreversible bad state.

              Acting like C++ with all the unnecessary shit it has is a requirement to develop large/GUI applications tells me you are not really arguing in good faith here.

              1. GNU SedGawk Bronze badge

                Re: Another day, another attempt to force this on us

                The dogma is unreal. Write some decent graphics in your language - then come and show us. Until then enjoy the multi-billion global media industry built on C, C++, and Assembler.

                Try some decent stutter free audio. Honestly have you considered you simply aren't very good at the task. Devoting insufficient time to verification and testing, and desperately clinging to the idea that if only you pick the correct language for implementation, magically verification is not required to the same degree.

                It doesn't matter if I cook for a king or a cat, I wash my hands, I clean my surfaces, I use fresh ingredients.

                C and C++ are reliable well specified choices, with known trade-offs, chief being, you are required to read the manual. It's an insult to some people, that you are forced to deliberately learn to use something correctly, not intuit an arbitrary design, based on not bothering to read a design decision.

        3. bazza Silver badge

          Re: Another day, another attempt to force this on us

          Rust is not a serious competitor for C++. It will never compete in that space - ever. It will take margin away from Golang and Python then fall-back into single digits of interest.

          I remember assembler programmers saying something similar about C... There's not many of them left.

          1. Anonymous Coward
            Anonymous Coward

            Re: Another day, another attempt to force this on us

            This is because C compilers allowed for inline ASM as direct consumption.

            Then C++ as a (close) subset of C allowed for direct consumption.

            The successor to C++ will need to allow direct consumption of C and C++ libraries. Rust is not this.

            I look forward to a successor to C++. But alas, it will not be in our lifespan.

          2. GNU SedGawk Bronze badge

            Re: Another day, another attempt to force this on us

            You're sadly mistaken - there are more working ASM programmers now than at anytime in history.

            Yes ASM has declined as the proportion of the industry but in real numbers that's the wrong horse to flog.

            Let me help you SIMD. https://lemire.me/en/publication/arxiv210910433/

          3. Duncan Macdonald

            Re: Another day, another attempt to force this on us

            Any competent programmer of the day knew that assembler was going to be mainly replaced by high level languages long before C appeared.

            FORTRAN made it apparent that the days of large assembler programs were dying.

            Good programmers could write approximately the same number of lines of correct code per day in Assembler or FORTRAN - but each line of FORTRAN could do the same amount of work as a dozen or more lines of Assembler. Also FORTRAN (and other later high level languages such as COBOL, ALGOL, PL/1, C etc) no longer required the programmer to know the inner details of a computer and a properly written FORTRAN program could be moved from one type of computer to another with little effort.

            One of the biggest security hazards in programming at the moment is the runtime inclusion of mountains of untested code in languages such as JavaScript. Because the linkage to the libraries is done at runtime from "somewhere on the internet" which may itself include more code from "somewhere on the internet" it is perfectly possible for a program to work properly when released but fail later because something changed in a library 4 or more levels deep in a "somewhere on the internet" tree which the original programmer never knew was being used.

      2. Phil O'Sophical Silver badge

        Re: Another day, another attempt to force this on us

        This is enforced by the language and compiler.

        Assuming that there are no bugs in the compiler and underlying runtime system.

        1. Jon 37

          Re: Another day, another attempt to force this on us

          Correct. But let's be fair here: that risk is not specific to Rust. Bugs in the C compiler or C standard library can have the same effect. And they have caused security issues in the past.

          1. Phil O'Sophical Silver badge

            Re: Another day, another attempt to force this on us

            Of course, but that means that no matter how perfect Rust is claimed to be, it is still exposed to many of the same bugs that exist with any language. Just because you've written your program in Rust doesn't mean that you don't have buffer overflows or stack corruption somewhere in the environment as a whole.

            1. This post has been deleted by its author

      3. martinusher Silver badge

        Re: Another day, another attempt to force this on us

        >So large programs written in C++ are highly likely to have memory safety bugs.

        So why focus on utilities which by their nature are widely used and so extensively tested pieces programs?

        The fundamental problem isn't memory safety as such, this is just a symptom of a much larger problem with programming methodology which I have called (rather pejoratively) the "Hose it the barn wall and see what sticks" school of software. Its more common than we admit and its primarily due to organizational problems, the need to churn out large amounts of code with only "if it doesn't crash then it probably works" levels of testing. Memory safety will catch important bugs, that's true, but the fact remains they shouldn't have been in the code in the first place.

    2. Blazde Silver badge

      Re: Another day, another attempt to force this on us

      https://godbolt.org/z/PsMr1xdfd

      As a C++ programmer for 30 years and a Rust programmer for 4 years, I find it way more difficult to review for correctness your simple bit of code than the equivalent in Rust. There's the advantage, even if you're one of the very few who can write sound C++ every time.

      1. GNU SedGawk Bronze badge

        Re: Another day, another attempt to force this on us

        I'd argue you're incompetent if you can't review that example comfortably in under ten minutes for the most pedantic review possible.

        It computes a dot product, it uses the STL.

        How on earth are we expected to take your opinion seriously if that level of complexity is considered to difficult to review for a thirty year veteran.

        This is the reference answer for my c++ interview question set for middle level candidates. It's a literal fizzbuzz level filter.

        1. Blazde Silver badge

          Re: Another day, another attempt to force this on us

          My statement was relative. I don't know how on earth someone who claims to be capable of writing flawless C++ could read it and get to me spending more than 10 minutes reviewing ~16 lines of code. I didn't mention minutes at all.

          1. GNU SedGawk Bronze badge

            Re: Another day, another attempt to force this on us

            You are suggesting that it being in C++ rather than Rust means you'd find it more difficult to review for correctness, because of some reason, you've not felt fit to elucidate.

            I never claimed to write flawless code. I'm mediocre at best, but I'm actually a C++ developer and I expect you as a fellow professional to review that without blinking.

            1. Blazde Silver badge

              Re: Another day, another attempt to force this on us

              because of some reason, you've not felt fit to elucidate

              For context, this is what I'd consider equivalent Rust code: https://play.rust-lang.org/?version=stable&mode=release&edition=2024&gist=31f47b74ecca1e909cf99b9608ae9e94

              - There's no indexing arithmetic to scrutinise

              - No awkward +1 fudges in loop (to be fair, the C++ could have avoided this by decrementing i after the loop body, but there'd still be more going on than ideal for such simple loop logic)

              - Even if you introduce non-local bugs such as making v1 and v2 different lengths the Rust code has no chance of accessing either array outside bounds

              - It's clearer that we're multiplying elements in 16 bits, accumulating in 32 bits, and only then promoting the result to 64 bits (I've taken the liberty of assuming a 64-bit machine in interpreting size_t). This might be a bug if you intended to accumulate in size_t (incidentally I did not spot this in my earlier review of your code). The Rust code helps us recognise this, not only because it says i32 in black-and-white but because in debug build it'll panic if the accumulator overflows.

              1. GNU SedGawk Bronze badge

                Re: Another day, another attempt to force this on us

                That's not the same code. You fail the interview.

                The code I posted does the multiplication in parallel and the addition in serial - it's lock free fork join parallelism, using the STL - you've pulled in random library because obviously Rust Stdlib is crap.

                While you are correct that X * X requires a 2X type for multiplication - That' again not the same code - with the same results.

                It's literally two different data types in your code, not one in mine.

                Again fail.

                I stand by my initial assessment, incompetent..

                1. Blazde Silver badge

                  Re: Another day, another attempt to force this on us

                  No, you're using an int to accumulate. This is one of the many gotchas of C++. 0 literal is considered an int preferentially ( https://en.cppreference.com/w/cpp/language/integer_literal ), which means type T in T accumulate( InputIt first, InputIt last, T init ) is int. Only after the accumulate is your T/int implicitly cast to size_t, and it may have overflown 32 bits by then. If you don't believe me check in Godbolt with um, 8 workers, slices of 8192 and starting vectors full of 64s and 128s. (*)

                  I did the sum in parallel because the result will be identical but achieved with better performance. 'Lock free' is a misnomer, any time you have 'lock free' code you're offloading the threading contention to the CPU which itself performs locking. You can see this clearly because you have costly lock asm instructions that guarantee atomicity and memory ordering. That may give better performance than heavy-duty locks sometimes but it's not a panacea compared to just reducing inter-thread data-dependencies. If the calculation is worth threading in the first place (this toy example isn't, that's besides the point) then you definitely prefer to merge 4 primitive values rather than 4 entire slices, and the Rust code will accumulate 'along the way' while multiplying, rather than doing 2 passes of v1, so more cache friendly.

                  You almost certainly have locks anyway, they're hidden inside the vector<jthread> destructor. If you don't have 'locks' in your code or the C++ library code then you're also giving up time-slices to the OS on the main/merging thread while the other worker threads aren't ready (because the alternative, spin-locking, is crazy in these circumstances) and that again involves locks, and context switches, and completely over-shadows whatever performance you think you're getting from not having locks. Don't get me wrong, nothing drains performance like locks done badly, but locks when appropriate are just totally okay and you can bog down your code trying to get rid of them. In any case despite this side-track, rayon uses the same strategy to coordinate threads, testing atomics and giving up time slices to the OS. There are some details like maybe you spin a couple of times before handing back to the OS but it's all about trade-offs in the end.

                  Rayon is as close to Rust stdlib for this kind of thing as you get, it's built on threading primitives that have gradually migrated from libraries into the standard. I note jthread support is a bit patchy still with C++ compilers while Rayon is supported on all Rust compilers (:troll:) where there are OS threads present, so the situation is not greatly different.

                  (*) I should however be promoting to usize as that's the equivalent to size_t in Rust, both are unsigned. I think that's a mistake but if it's not, the typical reason for using size_t is that you're going to do an allocation or other memory operation and that's dangerous if you might be casting a negative number ( https://cwe.mitre.org/data/definitions/195.html ). You can however cast i32 to usize in Rust quite happily so I'm not chalking that one as a win, but you do, as I said already, need to do it explicitly which means you won't get confused about what type your accumulation is happening in.

                  1. GNU SedGawk Bronze badge

                    Re: Another day, another attempt to force this on us

                    Firstly the entire point of the example is that the vector/array/RAII container imposes serialisation point, which allow for fork-join parallelism without the explicit lock, and corresponding opportunities for contention.

                    The code doesn't need explicit locks because it makes use of the fact that threads share an address space, so need only to avoid false sharing to happily update their own slice, with a read/modify/update operation.

                    It's a perfect example of what's wrong with Rust, it's broken a simple example and larded it with noise. The sum of products is not always the same as the product of sums, so again this is not the same algorithm. It's unlikely to matter for integers, but again still not a like for like.

                    Again it's about doing X in parallel and and then Y in serial. Doing X+Y in thread loops are missing the point.

                    This doesn't need a third-party library as it's an array of threads that do a trivial computation because the point is not the computation but the parallelism and the correct use of the cache.

                    It's utterly obvious what the access pattern is in my example, who can tell how many copies your example does.

                    It doesn't need anything but to use a stride which is a multiple of a cache line, or portably https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_size

                    Rust doesn't have a dog in this fight as you've amply proven.

                    What ever type you choose to accumulate the sum of a dot product of large arrays into an word is going to overflow. The wood for the trees.

                    If you try to make your code fast, and simple. You will fill blocks of memory- process whole blocks at a time using a primitive that will hopefully be a vectorised instruction, copy full blocks over the cache.

                    You will avoid locks, an implicit lock in the destructor is not a problem, as the language guarantees composed ordering.

                    The most complex code in that example is slice indexing.

                    1. Blazde Silver badge

                      Re: Another day, another attempt to force this on us

                      serialisation point

                      The Rust code serialises after the sum, I think you acknowledged that already and we're in agreement the Rust code parallelises a bit better, but this hasn't anything to do with how difficult it is to check for correctness.

                      The sum of products is not always the same as the product of sums, so again this is not the same algorithm. It's unlikely to matter for integers, but again still not a like for like.

                      Yes, it's the same algorithm. You're misunderstanding something but not explaining well enough that I can figure out what. Can you give some combination of constants and initial vector values that give a different answer for my code? If we're using floats that are not strictly commutative the results will differ by an epsilon or two at most, but we are not (in that case anyway neither result is more correct, but it would take me a few seconds to move the sum outside the threading if truly needed).

                      This doesn't need a third-party library as it's an array of threads that do a trivial computation

                      Just going to reiterate: you're using a C++20 feature compiler-makers have been slow to implement while I'm using a universally loved library that takes seconds to deploy and that's been solid since 2018 in a language that's barely that old. Someone rooting for C++ really doesn't want to get into an argument about language standards. Boost was unofficially flying the C++ language standards flag for several decades while the standards committee sat on their hands. Don't get me wrong, I'm glad that's no longer the case but please get down from that horse.

                      because the point is not the computation but the parallelism and the correct use of the cache

                      Not sure what your point is but it feels a good moment to mention I mirrored the behaviour of your code. If I did it the performance way I wouldn't have mutated v1 vector because that's much more costly than reading and accumulating into one value per thread. Your code leaves v1 in a particular state I felt it was important to replicate despite costly main memory writes. In truth, LLVM may well optimise away those inconsequential writes, but I tried.

                      who can tell how many copies your example does

                      I can tell you, none. In Rust if you do a copy you'll either have a clone() or you're creating a new array/vec involving a light Copy type. The type here (i16) is Copy which would mean very fast SIMD memcpys, but they are not happening anyway. Even when you think you're creating a new container it's usually better at copy elision than C++. I've used Rayon in much more complicated scenarios where an extra array is needed on output and I can tell you you won't be performing those scenarios in C++ with jthread without an extra buffer either.

                      https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_size

                      Yea you can apply atomic padding in Rust. It's not mandatory, perhaps it should be but there's a heavy trade-off with memory usage in some scenarios. The usual way is just to manually align structs containing atomics to 64 bytes because everything has cache lines that long currently. It's a bit foolish trying to generalise and future proof because we don't know what future hardware will look like.

                      The most complex code in that example is slice indexing.

                      Yea, this is what I started off saying. It's needlessly complex. The danger of getting it wrong allows C/C++ developers to imagine they're playing with fire but too smart to avoid getting burned. Let's be honest some of them really love that and it's a problem.

                      1. GNU SedGawk Bronze badge

                        Re: Another day, another attempt to force this on us

                        I'm sorry but you are doubling down on wrong.

                        Fork - Join - Fork the threads to do the multiplication, Join to do the sum.

                        You are running multiplication + addition in the threads, then waiting for them all to finish.

                        You do the sum in the threads, so you do a different algorithm to calculate the same outcome. entirely missing the point.

                        JThread is stdlib and calls join, Raython is a third-party crate - so no dice. you don't need anything but join if you need a third-party lib to do this the language is broken.

                        Multiplications of arrays in a loop is as far from complex as is possible with computation. The guff about this being somehow using advanced features is belied by this being the same example since C++98.

                        Sure the plumbing had to be written, in C++11 you had to call join yourself in a std::thread wrapper. The Functor became a lambda.

                        Honestly you do yourself no favours by suggesting slice indexing is complexity and that heap of line noise is simple, when you've had to pull in a third party library and still cannot get the right answer.

                        You've decided that an explicit size of integer is meaningful, and are laser focused on that when it make naff all difference.

                        This is literally the most basic example, and you are suggesting we adopt your opinion based on that.

                        Because counting by fixed multiples is "complicated". Thirty years experience you claim, doing what?

                      2. GNU SedGawk Bronze badge

                        Re: Another day, another attempt to force this on us

                        We don't agree about literally anything.

                        You've taken an embarrassingly parallel problem with a closed form solution and worked very hard to make it a poor copy of the ranges API.

                        The side of condescension is not helping.

                        You've made it slower, harder to read, and incorrect.

                        You've broken the auto-vectorisation - and to boot, you don't see it at all.

                        You've broken the data access pattern, and you cannot get, your code is worse, in every way.

                2. Phil Lord

                  Re: Another day, another attempt to force this on us

                  I think that your conclusion that the Rust stdlib is crap is flawed. The idea of having a small stdlib was an design decision. There were attempting to avoid the problem we have seen in other languages which have "batteries included" standard libraries. That sounds like a good idea, but over time, some of these batteries tend not to be so good, and so the libraries atrophy. Python is the obvious example with Requests and the standard library http support being a good example.

                  Rust instead provides good mechanisms and tooling for supporting dependencies as first class entities (i.e. crates). Pulling one of them in to run parallelism is not unexpected and not really evidence that stdlib is crap.

                  You might argue that the Rust approach is flawed, but that is a bigger and more general question.

                  1. GNU SedGawk Bronze badge

                    Re: Another day, another attempt to force this on us

                    It's a hollow joke, that this interview example is being larded as if it's doing something complex.

                    if you need a third party lib to put four threads into an array and then call join - your language is broken.

                    The STL and the Rust Stdlib are the equivalents. If it's not in the stdlib, you can't use it as demonstration of how much better life is in your world,

                    That code is pretty simple and a like for like equivalent shows rust for the shit show it manifestly is.

                    My code makes two passes over code using vectorised multiplication and vectorised add. The data access pattern is obvious, it minimises allocation to the threads and the vector (could replace with std::array).

                    This is a simple example which you should be able to replicate in a language with threads, and lambda. This is the sort of code that needs to be considered for moving to Rust to compete with C++.

                    So far the pretender can't even see the throne, let alone aspire to the position.

                    It's also deeply arrogant to re-arrange the algorithm to break the core properties, while opining on efficiency and safety - again stuff correctness - feel the width.

                    in doing so breaking vectorisation and imposing a 4x slowdown - nice.

                    1. Phil Lord

                      Re: Another day, another attempt to force this on us

                      "

                      if you need a third party lib to put four threads into an array and then call join - your language is broken.

                      The STL and the Rust Stdlib are the equivalents. If it's not in the stdlib, you can't use it as demonstration of how much better life is in your world,

                      "

                      I think that I would disagree with this. What you are saying is, essentially, that C++ has a bigger standard library than Rust, therefore it is better. Importing crates is the way that you get additional functionality. It would be like arguing in that, in your example, Python is better than C++ because in Python list manipulation is there by default, while in C++ you have to import vector.

                      Is Rayon a third party lib? Well, in a sense, yes, although the developers are in that case are part of the Rust core team. There are a set of crates which are very widely used, and well supported. rand, clap, serde, syn and quote and so forth all leap to mind. Arguing that a comparison is only valid if you exclude all of these things is not reasonable.

                      A much more valid criticism is that the Rust dependency supply chain is not so clear about which crates are well supported and that is needs some "official" ones. It is a known issue and one that the Rust foundation is working on.

                      1. GNU SedGawk Bronze badge

                        Re: Another day, another attempt to force this on us

                        What you are saying is, essentially, that C++ has a bigger standard library than Rust...

                        I see how that come across, and I also think it's somewhat of a strawman. Let's try to be nuanced - I think you have to accept that part of what people want from C++ includes the stability and that means the standard defines what you can rely on. Boost is not STL despite many committee members being boost contributors.

                        This is just simple code as a placeholder for more complex computation. The point is you don't need a third party library to do this. its basic threading, and you should be able to do this in any language, it should look roughly the same in any language.

                        This should be a clear win for Rust, and it falls so short because behind the curtain, no new ideas, no compelling advantage. Every useful idea from functional programming has slowly carefully been gently made available to the C++ community, so our code keeps evolving.

                        There is std::expected / std::variant / constexpr computation / perfect function forwarding - Rust has what? seriously what ? You made it compile so you're happy!

                        We routinely profile, performance test, read the assembly generated. The front end language is a component of a language eco-system which Rust has smeared itself into, and claims an advantage with using Rust to call C libraries rather than C++ for C libraries, or even Python for C libraries.

                        Port PhotoShop or LogicPro to Rust then we'll talk. Port one of the older game engines to Rust, see how much frame rate you lose.

                        1. Phil Lord

                          Re: Another day, another attempt to force this on us

                          "Let's try to be nuanced - I think you have to accept that part of what people want from C++ includes the stability and that means the standard defines what you can rely on."

                          Yes, indeed. It is a very similar argument to Python's batteries included philosophy. You can do all the things you want to without dependencies.

                          I don't know how it is in C++ so much, but the probably is that you can do HTTP in python without dependencies but most people use requests. You named boost yourself; while it does not replicate std library in the way that requests replicates HTTP support, it falls into a similar category. Many C++ developers find boost indispensible.

                          Rust has taken the other approach. It has said that it will have a small library, and use dependencies. On the other hand, dependencies in rust are a core part of the ecosystem and are well supported in both the language and the tooling. That isn't true in python for instance -- it has had many options over the years, but it only recently got a standard "project specification" file format (which is partly borrowed from Rust); and the tooling is still behind Rusts and not standard (i.e. pipenv, poetry, uv). My experience with C++ is much less, but as IIUC, it still does not have this.

                          I agree with you, though, as it matures it will need a core set of libraries that you can depend on strong stabilities/future proofing guarantees probably linked to the same ones that Rust itself supports. These will still be delivered by crates, though, I am sure. Rust will access "standard" libraries in the same way that it accesses any other third party dependency.

                          What does Rust have? Well, you already know that. It has a strong type system which it also uses for lifetime management, meaning that it provides strong safety guarantees. That is the thing that is it's unique sales point.

                          Personally, I used it because I wanted to do something fast, I have done lots of functionalesque programming. I had a choice: I could learn C++, GO or Rust in enough detail to do this. I choose Rust. In practice, I found it quite nice to code with and it fulfilled its promise of being fast. I see quite a few other people in my area (scientific computing) making the same decision.

                          I've no desire to port PhotoShop. It's not something I use, nor something I want.

                          1. GNU SedGawk Bronze badge

                            Try to not make shit up.

                            So we have a Rust advocate who doesn't know C++, telling us we're descended from hamsters, and wear elderberry cologne. Just like all the others.

                            C++ has a stdlib.

                            C has a stdlib.

                            Rust has a stdlib.

                            The C and C++ stdlib are well defined and allow actual usage -that's C and C++. The Rust stdlib is a limited as it is, because it's a toy language. So who cares about third-party support.

                            If you need if for this example, your language is rubbish. The truth is, you can do this in plain rust without third party code - it just looks horrid.

                            Here's what Jthread looks like - https://github.com/matklad/jthread-rs

                      2. GNU SedGawk Bronze badge

                        Re: Another day, another attempt to force this on us

                        list in python and vector in C++ are part of the standard library.

                  2. GNU SedGawk Bronze badge

                    Re: Another day, another attempt to force this on us

                    I'm not out here arguing Rust is suitable as a C++ replacement - it's obviously unsuitable, underspecified, and over-engineered missing basics in the stdlib, leading to needing third party support for basics.

                    That's Rust - the language and Stdlb - otherwise you might as well include all of the global C and C++ codebase when evaluating C++. It's nonsensical - the stdlib is the portion I can expect another working programmer to be familiar with.

                    You can argue - and not being a Rust Guy, I'll take your word - that I'm being too pedantic/ that really this is basically pthreads/boost asio/bsd sockets - e.g. a well known platform library.

                    But come on, surely you can do this in vanilla rust without difficulty, because all that's required is to call join before doing the sum. Okay a language with destructors makes that easier,

                    but you could use a latch or some other means.

                    This should be the poster child for "fearless-concurrency" - and rust has what to offer here?

                    1. Phil Lord

                      Re: Another day, another attempt to force this on us

                      All depends on what "vanilla rust" means to you and why you think it is important.

                      With "vanilla C++" can you depend on the boost libraries, have them downloaded in a clear, specified and reproducible way that you know will compile on someone elses machine? That works with Rust. Does it with work with C++? Or Python?

                      1. GNU SedGawk Bronze badge

                        Re: Another day, another attempt to force this on us

                        The example in plain C++. No boost required. Literally the point being made.

                        Rust is a bug ridden underspecified front-end to LLVM, without any value to offer for working programmers. It's a trojan horse pushed by undereducated, inexperienced people, and the US Intel community https://www.theregister.com/2023/12/07/memory_correction_five_eyes/.

                        1. Phil Lord

                          Re: Another day, another attempt to force this on us

                          I don't really care about your example. The point being made is that if you do want to use boost, can you specify this in a standard way, with good tooling to make sure it all happens? In C++, the answer is no. In Rust, the answer is yes.

                          These are two very different design philosophies. Rust says "have the smallest stdlib you need, then use dependencies and make them usable". C++ says "have a good standard library, then add libraries if you must". Advantages and disadvantages for sure. But to compare Rust stdlib to C++ stdlib and discover that C++ has a bigger one is, as I have noted, not a good argument.

                          1. GNU SedGawk Bronze badge

                            Re: Another day, another attempt to force this on us

                            The argument is just you don't know rust any better than you know C++, as another person has replied, you are mistaken and this is all a distraction from the point.

                            The original reply has posted some rust code, that's perfectly reasonable, infact produces quite decent ASM output, even if it's a bit smeary, the end result seems reasonable.

                            Frankly if you're going to defend rust, or slate C++, you should bother to learn the languages rather than muddy the waters, with nonsense about dependencies.

                            The stdlib is a the minimal set you can rely on - everything else can evolve at different rates. Installing software written in any language should involve unpacking a staged directory from a tarball into place.

                            It's stupid to suggest language specific dependency management, simply because some users of your tool can't afford the nickel for a real computer. https://forums.theregister.com/forum/all/2021/06/21/containers_vs_vm_for_mon/#c_4279211

                            Package your code as a deb/rpm and install it properly through the package manager.

                            1. Phil Lord

                              Re: Another day, another attempt to force this on us

                              Believe that if you want. I can say for sure I know Rust far better than I know C++.

                              Installation of dependencies using deb/rpm is platform specific and because it will not be specified in the repo does not support a reproducible build.

                              1. GNU SedGawk Bronze badge

                                Re: Another day, another attempt to force this on us

                                Reproducible builds involve controlling for sources of drift.

                                Does your code embedded a build time string - congratulations - non-reproducible.

                                You don't install during a build, so it makes zero difference where your dependencies come from.

                                You should be building offline - so all dependencies are available at build time with controlled sources. You are pushing myths about your advocated language and patently don't know your elbow from your fundament.

                                1. Phil Lord

                                  Re: Another day, another attempt to force this on us

                                  "You should be building offline - so all dependencies are available at build time with controlled sources."

                                  Yes, I agree. That is how it works in Rust.

                                  1. GNU SedGawk Bronze badge

                                    Re: Another day, another attempt to force this on us

                                    No - it downloads half the internet at the slightest provocation leaving you atop a mile high pile of unaudited code. https://vincents.dev/blog/rust-dependencies-scare-me/?

                                    Reproducible builds don't just happen by virtue of your magic language, https://github.com/rust-lang/rust/issues/129080

                                    I've made reproducible builds in various languages for some years now, I know a little about this subject. This is for Time - the lowest of low hanging fruit in the build community

                                    https://reproducible-builds.org/docs/source-date-epoch/

                                    Suffice it to say, you don't get anything from Rust that you don't get elsewhere including problems around reproducible builds - like other languages - Rust can be made reproducible with care - but it's not free and not out of the box with $YOLO dependencies.

                    2. Blazde Silver badge

                      Re: Another day, another attempt to force this on us

                      Since you're hung up on this and some Rust coders are now incorrectly implying outside crates are necessary here's the same with only std. I even moved the sum outside the threading like you wanted even though it'll be worse for performance (as it happens it made for simpler code since I can ignore the return values of the threads):

                      https://play.rust-lang.org/?version=stable&mode=release&edition=2024&gist=303bbb6171701f9b90bf023f2f487563

                      A little more verbose than with Rayon but not really. Rayon's true power lies in creating trees of nested tasks with worker threads which work-steal when they've finished their own tasks, something which would require an extra level of abstraction in C++ too, but it's overkill for this task. I am truly sorry for misleading you a '3rd party library' was necessary.

                      I mirrored the signed 32-bit to unsigned 64-bit promotion too. So this is now the exact same pattern as your C++ code, with the sole exception that it will catch some underflows/overflows, depending on compile mode.

                      You might be interested to know Rust's scoped threads are very similar to C++'s jthread, they join automatically when references to them are dropped. In Rust however this isn't a mere convenience but is essential for sharing data with strong concurrent-aware memory-safety guarantees because we can allow threads to borrow references to data owned by the spawning thread, safe in the knowledge that the spawning thread will outlive the spawned thread. I think that's neat but I'm sure you won't. It's also why there're no unnecessary copies, as you feared there might be. The child threads gain temporary ownership of v1/v2 but the main thread can access them again when safe to do so. The borrow-checker enforces this, so for example the same pattern without a scoped thread block won't compile. This is the kind of feature which backs up phrases like 'fearless concurrency'. I am absolutely certain other languages will get there soon so I'm not a cultist holding Rust up as some perfect forever-language, but it is absolutely doing a lot of useful stuff that C++ is currently not doing.

                      1. GNU SedGawk Bronze badge

                        Re: Another day, another attempt to force this on us

                        Thank you, I appreciate the fuller example.

                        We can now look at this, and so far, I'm looking at iterators over slices, when the other looked like it used an integer index - i.e. the native addressing mode for arrays - so are we making a copy of the iterators or what.

                        I put it into goldbot so it can be compiled - perhaps you can see what's needed - It's easier to have a look at the assembly.

                        https://godbolt.org/z/fW4b973vs

                        1. GNU SedGawk Bronze badge

                          Re: Another day, another attempt to force this on us

                          I'm not a Rust person so this might be incorrect.

                          Iovec from readv/writev

                          #include <sys/uio.h>

                          struct iovec {

                          void *iov_base; /* Starting address */

                          size_t iov_len; /* Size of the memory pointed to by iov_base. */

                          };

                          for (slice_v1, slice_v2) in v1.chunks_mut(SLICE_LEN).zip(v2.chunks(SLICE_LEN)) seems create an array of iovec, then a second array of iovec, then flattens them into a third array of pairs of iovec, then iterates over this composed array.

                          That's a load of copies there, not of the data but it's giving me what ROI?

                          1. Blazde Silver badge

                            Re: Another day, another attempt to force this on us

                            No no no. I don't know where you've pulled iovec from, that's not Rust. The best to way to interpret iterators is that they're an abstraction that the compiler can reason very easily about. The end result is just a begin pointer and a length (together: a slice) passed to the threads, or something mathematically equivalent that the compiler has conjured up. The compiler ensures memory safety so the asm can be as dirty and hacky as needed, there's no need for copying. In fact there's often less copying than in C++ because there are less standards imposed on what actually happens in memory.

                            1. GNU SedGawk Bronze badge

                              Re: Another day, another attempt to force this on us

                              I know Iovec is not rust. as far as I understand what chunk and chunk_mut are doing is populating a slice structure in Rust - which is roughly a pointer/size or Iovec in C.

                              I'm trying to map what is happening to the code. So far it seems like you've constructed an array of slices, based on copying slice structures, and them collecting them into another array.

                              You don't fill the array - so I think you're incorrect that one array can not be mutable.

                              1. Blazde Silver badge

                                Re: Another day, another attempt to force this on us

                                Okay yes, there's a pointer/size (aka slice, aka fat pointer). These aren't in an array though, there's just 8 of them produced 2 at a time (one of each pair pointing into v1 and one into v2) that are passed to the threads. The threads mutate v1 but they don't need to mutate v2, that's just how you wrote the original code. I don't really understand your last line (I'm incorrect that one array can not be mutable?). v2 isn't mutated, but it could be if needed. (I still maintain in this simple case it would be better for each thread to accumulate the mutations itself and avoid any need to synchronise the writes back to v1, but sure, maybe the side-effect of the v1 changes is somehow integral to whatever functionality we're simulating here).

                        2. Blazde Silver badge

                          Re: Another day, another attempt to force this on us

                          You need compiler flags '--edition 2021 -C opt-level=3 -C target-cpu=native' in Godbolt. I'm predicting you're going to complain there's more asm code in the Rust version so I'll pre-empt that by pointing out that's it's mainly robust error-handling for all the edge cases the system calls might produce. The hot paths are remarkably similar in both, unrolled loops and vectorisation for both the multiplying and adding, a smattering of allocations to handle the threads. What you'd expect.

                          1. GNU SedGawk Bronze badge

                            Re: Another day, another attempt to force this on us

                            The amount of Asm is not that important, but I'll grant you it vectorises the multiplication and addition. https://godbolt.org/z/c3zvTeG5T

                            I find it quite hard to map what's happening back to the source with compiler explorer. It looks like it did a decent job of packing the code into a dense block of vectorised adds.

                            Are there other tools you'd recommend for rust that might be better for this, as it's much easier to do for C++

                            I think it seems to unroll the loop quite well and the generated code looks quite reasonable, I'd not want to audit that source to the assembler based on this simple example.

                            I grant you that's a minority concern.

                            1. Blazde Silver badge

                              Re: Another day, another attempt to force this on us

                              Godbolt is really good at mapping the asm back to specific C++ lines. That's partly because Matt has put effort into refining it, but it's also because C/C++ specifically require functions to have unique addresses in memory. Rust code and resulting asm are more disconnected because the compiler is freer to transform the code, inlining and smearing the higher-level functionality to make it harder to map but hopefully with faster execution. (Even so I am a bit surprised how bad the mapping is in this example).

                              My recommendation is not to worry too much about the actual asm but to benchmark it in reasonable real world scenarios (with randomised data to thwart compiler optimisation of constants). Only when you perform instruction-level measurements of branch mis-prediction or pathological fetches etc do you really need to untangle which line of Rust is responsible for a particular asm instruction, and in those cases it's usually pretty obvious where the bottleneck is likely to be.

                              1. GNU SedGawk Bronze badge

                                Re: Another day, another attempt to force this on us

                                Perhaps a Rust Godbolt will arise.

                                That's what I mean by you need to fill the arrays - It compiled but surely you have a memset wrapper primitive which is less horrid than this rust, I've bodged together.

                                let mut v1 = vec![2i16; SLICE_LEN * MAX_WORKERS];

                                let mut v2 = vec![2i16; SLICE_LEN * MAX_WORKERS];

                                for e1 in v1.iter_mut() {

                                *e1 = 2;

                                }

                                for e2 in v2.iter_mut() {

                                *e2 = 4;

                                }

                                std::thread::scope(|s| {

                                for (slice_v1, slice_v2) in v1.chunks_mut(SLICE_LEN).zip(v2.chunks(SLICE_LEN)) {

                                s.spawn(move || {

                                for (e1, e2) in slice_v1.iter_mut().zip(slice_v2.iter()) {

                                *e1 *= *e2;

                                }

                                });

                                }

                                });

                                /* the rust above is supposed to do this, which equates to initialising all members of the array to the value */

                                v1.fill(2);

                                v2.fill(4);

                                /* run multiplication in parallel */

                                1. Blazde Silver badge

                                  Re: Another day, another attempt to force this on us

                                  Ah,

                                  vec![2i16; SLICE_LEN * MAX_WORKERS]

                                  This expression already creates the Vec initialised with all 2s. (2i16 is 2 of type signed 16 bit integer). You don't have uninitialised data(*) in Rust, strict RAII is one of the core principles.

                                  (*) To be more precise there is a special MaybeUninit wrapper for low-level use which tracks memory that absolutely needs to be uninitialised and prevents it polluting non-unsafe code, and even in unsafe code you're prevented from doing anything too dangerous with it.

                                  1. GNU SedGawk Bronze badge

                                    Re: Another day, another attempt to force this on us

                                    The godbolt output looks a little better if you remove the -C cpu native -

                                    That seems a little inconvenient, I don't want a pointless memset of a large array when the value maybe computed and overwriting that space - but meh, presumably that's tweakable with your MaybeUninit.

                                    In this case it's helpful but Rust really wants to prevent me working with arrays efficiently, which is 90% of the code - do stuff fast in-place in arrays, avoid copies.

                                    I see the idea is to push more into the template language and provide a lazy evaluated result which is then optimized. All of which makes me feel like compiled python.

                                    The principle being, let the compiler worry about layout and access. I spent a little bit of time trying to figure out how explain to the rust compiler that I wanted to write into an array.

                                    ultimately this was fruitless and I lost interest.

                                    I guess my question is if you don't care about layout and access - why bother with a statically typed language at all?

                                    I guess if you take it as a faster python then you get larger application with a fluent interface and less issues than dynamically typed applications in scripting languages or with anaemic type-systems like golang.

                                    I guess if you are proficient with Rust, you can use it as a better python. I don't see the translating all the complex array code to slices being viable without introducing errors, but fine if you wrote it fresh, it's not much different.

                                    With simpler code - there is less scope for the sort of errors that rust is presumably trying to prevent, so perhaps that encourages more complex code in Rust, or just empowers more junior developers..

                                    I can't see myself switching to Rust tbh, but it's been an interesting diversion, thank you again.

                                    1. Blazde Silver badge

                                      Re: Another day, another attempt to force this on us

                                      There's no extra memsetting or copying (at least if you get rid of the unnecessary fills you added). I meant that there's no uninitisaised data at the language level. In the resulting asm of course there'll be lots, but it'll be statically guaranteed not to be treated as initialised data (give/take bugs in unsafe code).

                                      You cannot accidentally copy a Vec in Rust (outside of the expected amortized constant time growth if you don't pre-empt the final capacity), because it doesn't implement the Copy trait. You need to be explicit by .clone() ing it, and of course you think twice before doing that because it can be costly.

                                      The layout and access is precisely the same as in C++. Two arrays on the heap. Where on the heap? We don't know, the allocator takes care of that and it's non-deterministic in general. In C++ and Rust alike. If you care about layout you need to go closer to the metal. [Edit: I just realised I switched the Rust code from on-stack arrays like your C++ to heap-allocated Vecs at some point. I can't remember why and it isn't necessary (simply remove the two vec! to go back to arrays) but they are quite large for the stack anyway and a couple of extra one-off allocations and pointer derefs isn't hurting performance.] It's absolutely not like Python which uses garbage collection and almost every trivial thing is an object with massive heap fragmentation and constant cache misses.

                                      I don't see the translating all the complex array code to slices being viable without introducing errors

                                      More likely you'll find and fix bugs, but it's a lot of work so don't try it unless your old code base is known to be quite buggy or is especially security sensitive.

                                      I can't see myself switching to Rust tbh, but it's been an interesting diversion, thank you again

                                      Fair enough, respect for being open-minded enough to try it even though you had some strong prior views on it. I only encourage people to do that before bad-mouthing it because there is a lot of misinformation from the die-hard C/C++ crowd :)

                                      1. GNU SedGawk Bronze badge

                                        Re: Another day, another attempt to force this on us

                                        Thanks again for the effort.

                              2. GNU SedGawk Bronze badge

                                Re: Another day, another attempt to force this on us

                                It seems to do a bit better job with this variant, and If im not mistaken, you are only using a single thread - rather than the MAX_WORKERS threads in the original

                                This version is not terrible for legibility with only the slice copying as extraneous to the algorithm, leaving the comparison

                                /* C++ */

                                auto end = i * slice;

                                for (auto begin = end - slice; (begin != end); ++begin) {

                                v1[begin] *= v2[begin];

                                }

                                vs

                                /* Rust */

                                for (slice_v1, slice_v2) in v1.chunks_mut(SLICE_LEN).zip(v2.chunks(SLICE_LEN)) {

                                for (e1, e2) in slice_v1.iter_mut().zip(slice_v2.iter()) {

                                *e1 *= *e2;

                                }

                                }

                                // If you use `main()`, declare it as `pub` to see it in the output:

                                // pub fn main() { ... }

                                pub fn main() {

                                const MAX_WORKERS: usize = 4;

                                const SLICE_LEN: usize = 1024 * 64 * 4;

                                let mut v1 = vec![2i16; SLICE_LEN * MAX_WORKERS];

                                let mut v2 = vec![2i16; SLICE_LEN * MAX_WORKERS];

                                v1.fill(2);

                                v2.fill(4);

                                /* surely this is one thread, not four */

                                std::thread::scope(|s| {

                                for (slice_v1, slice_v2) in v1.chunks_mut(SLICE_LEN).zip(v2.chunks(SLICE_LEN)) {

                                s.spawn(move || {

                                for (e1, e2) in slice_v1.iter_mut().zip(slice_v2.iter()) {

                                *e1 *= *e2;

                                }

                                });

                                }

                                });

                                let mut dot_product: u64 = 0;

                                for e1 in v1.iter() {

                                dot_product += *e1 as u64;

                                }

                                println!("Got dot product of v1.v2: {dot_product}");

                                }

                                1. Blazde Silver badge

                                  Re: Another day, another attempt to force this on us

                                  /* surely this is one thread, not four */

                                  It's actually 5. chunks_mut produces 4 chunks which are looped over and each loop iteration spawns a worker. The main thread then waits at the end of the scope block for all 4 workers to join. In my original Rayon version the main thread would become a worker so there were only 4 total (or only 4 running at a time anyway).

                                  1. GNU SedGawk Bronze badge

                                    Re: Another day, another attempt to force this on us

                                    I find myself both vindicated and refuted. The language once you strip all the noise away could be plugged into a number crunching kernel (refuted) I'm not sure it's a win for legibility (vindicated).

                                    I'm a little troubled that there is a specific construct for the thread scope, rather than it being a property of the container.

                                    It seems that essentially there is a fair amount of arranging for simple collections, and relying on compile time evaluation to make it something reasonable.

                                    For example building in -O0 shows the memcpy calls for the slices, which by the time optimization completes has disappeared replaced with the unrolled literal code - so dense code decent generated output.

                                    Overall, I'm intrigued. Audit is a still open question - but that's a tooling problem and presumably other people are working on that.

                                    Thank you again for your contributions.

                                    1. Blazde Silver badge

                                      Re: Another day, another attempt to force this on us

                                      Legibility is what you're used to. It was an adjustment for me for sure, but there's less detail hiding in arithmetic because of the functional constructs, less off-by-one errors. Less wondering is that resource freed properly? Is that iterator valid? And so on. Because much of that checking is off-loaded to the compiler. But of course you need to know the language pretty well before you can trust what the compiler brings to the code review.

                                      For example building in -O0 shows the memcpy calls for the slices

                                      There's a bit of this in any compiled language, but I actually think it's one of the most intriguing things about Rust. It's a modern language in the sense that it's built with awareness of, and to rely on the deep optimisations LLVM performs. There's a less-is-more approach to the high-level abstractions which stands in stark contrast to the low-level tinkering C, and to a lesser extent C++, encouraged. Yet it somehow works just as well. It also relies on very demanding compile-time type-checking/borrow-checking. It wouldn't have been possible 20 years without unreasonable compile times. Even 15 years ago the relative immaturity of compiler optimisations would have reduced it's performance or forced language design compromises. So it's not intrinsically better than C++, it just leans better into the resources we're able to invest in software development at the current point in time, and as a result wins some security guarantees that have also never been more important than at the current point of time. Capabilities and requirements will continue to evolve so no language can really afford to sit still.

                      2. GNU SedGawk Bronze badge

                        Re: Another day, another attempt to force this on us

                        Firstly, thank you for your contributions.

                        I'd quite like a loop over arrays with integer indices because I want specific assembly generated. The idea is to leave the data alone, and just bump the index.

                        Also work stealing thread pool in C++ are widely available and sometimes undesirable as pinning a thread to a core, avoids unneeded bus traffic.

                        ...scoped threads ... join automatically .. sharing data with strong concurrent-aware memory-safety guarantees ... safe .. the spawning thread will outlive the spawned thread.

                        Yes - that's the point of RAII using threads, and why Rust is not offering anything new - it's a pattern not a property of Rust.

                        Your code doesn't compile btw despite "fixing" my code

                        rror[E0599]: no method named `try_into` found for type `i32` in the current scope

                        --> <source>:22:10

                        |

                        19 | let dot_product: usize = v1.iter()

                        | ______________________________-

                        20 | | .map(|e| *e as i32)

                        21 | | .sum::<i32>()

                        22 | | .try_into()

                        | |_________-^^^^^^^^

                        --> /rustc/05f9846f893b09a1be1fc8560e33fc3c815cfecb/library/core/src/convert/mod.rs:613:8

                        |

                        = note: the method is available for `i32` here

                        |

                        = help: items from traits can only be used if the trait is in scope

                        = note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021

                        help: trait `TryInto` which provides `try_into` is implemented but not in scope; perhaps you want to import it

                        |

                        4 + use std::convert::TryInto;

                        |

                        help: there is a method `into` with a similar name

                        |

                        22 - .try_into()

                        22 + .into()

                        |

                        error: aborting due to 1 previous error

                        For more information about this error, try `rustc --explain E0599`.

                        Compiler returned: 1

    3. James Anderson Silver badge

      Re: Another day, another attempt to force this on us

      C++ is highly unstable every release has newer weirdest features, and, depreciated older broken features. As for readability people complain about PERL but much of C++ code really does look like line noise.

    4. DS999 Silver badge

      How is this "forcing it on us"?

      Do you intend to personally peruse the sudo code, or are you now or do you intend to be in the future to contribute changes/improvements to that package? If not then STFU.

      And "performance", seriously? That's got nothing to do with sudo. Is it executing too slowly for you or something?

      This is the proper way to use memory safe languages like Rust - a targeted approach in places where it matters. I would have agreed with you if the article was about an effort to rewrite all Linux software in Rust. But this is just one package, but one for which security is paramount but is small enough that it didn't involve too much effort to port to Rust.

      1. GNU SedGawk Bronze badge

        Re: How is this "forcing it on us"?

        As it happens I've already got a barebones variant of sudo - it's called set-user used mostly in small containers.

        There is not that much code to set a few environment variables and a call to getpwnam_r / initgroups / setgid / setuid / execvp

        It's less than 80 lines of C including the error handling and argument parsing.

        You should try it yourself, see how much value the Rust variant is adding.

        1. Anonymous Coward
          Anonymous Coward

          Re: How is this "forcing it on us"?

          See doas:

          https://en.wikipedia.org/wiki/Doas

          1. GNU SedGawk Bronze badge

            Re: How is this "forcing it on us"?

            Cheers looks a lot more fully featured than my efforts, might be worth switching.

    5. Uplink

      Re: Another day, another attempt to force this on us

      You say: "If you use simple code, and the STL"

      I think I see the problem. It's that "if". You're relying on humans. Put that into mandatory tooling and then we may have a fair comparison.

      Using the car analogy, it's like this: a car that checks the blind spots for you vs an older car where "if you check your blind spots religiously" everything should be fine. But as long as there's space for slipups, there will be slipups.

      1. GNU SedGawk Bronze badge

        Re: Another day, another attempt to force this on us

        Rust is not simple. It's a horrid ML variant dis-functional language.

        If you can't hire competent people, your results will be poor. C++ is intended to make life easier for professionals working on large long lived systems. It scales up from very small friendly code, to big proper iron.

        Rust offers me nothing in this space, I get supply chain attacks with Cargo as part of the build process - because I'm incapable of installing software in a prefix and exporting a couple of environment variables.

        While this noise has been going on, C++ has slowly gained quality of life improvements, and you can adopt them at your own pace in small doses.

        All I get for switching to Rust is problems, not a single advantage. This thread hasn't measurably generated new answers from the last time this came up

  2. jj_0

    Why not bite the bullet and do a libc6-rs?

  3. GNU SedGawk Bronze badge

    I don't see the niche for Rust. I either want higher level so a scripting language with a decent repl like ruby, or I care about the lifetime of my systems and being stuck on a single source llvm-frontend is troubling.

    Nobody has answered the matter of "Fully Countering Trusting Trust through Diverse Double-Compiling" https://arxiv.org/abs/1004.5534

    It's based on saying C has an issue which is addressed with destructors and scoped resource management, either in extensions or pre-processing, or with language support in C++. Therefore Rust, no linkage is offered, just a conclusion.

    I don't see why a functional language with horrid syntax and glacial compilation is offered as some advancement over modern C++ or even modern C with the standard extensions.

    It seems that Rust appeals to a more axiom focused developer who feels the grubby business of computation is rather beneath them, and would rather something else handle it.

    C and C++ are for software that has to last, and be upgraded for a decent length of time, perhaps longer than one's internship rewriting decades old tooling might afford.

    1. Headley_Grange Silver badge

      "It seems that Rust appeals to a more axiom focused developer who feels the grubby business of computation is rather beneath them, and would rather something else handle it."

      Rust might appeal to companies who think they can shorten or even skip some bits of the software development process because Rust will take care of stuff they used to have to manage with reviews, testing and, you know, good SW engineers. I can imagine some of the people I've worked for coming back from a conference jolly all fired up with "this new language that's going to take 20% off our development costs because you can't write bad code with it" speeches.

      1. GNU SedGawk Bronze badge

        I agree, there is a literal quote from the last time this came up,

        Because Rust guarantees that you'll do it without introducing undefined behavior, even if you don't fully understand it, which carries a side effect of making it much easier to learn. The compiler also tells you exactly why what you're doing is wrong and even suggests how you might fix it. This may be hard for you to believe, but you literally can not screw this up if you're using Rust. Really. The language honestly delivers on what it promises.

        But it compiled how can it be buggy as fuck.

      2. Anonymous Coward
        Anonymous Coward

        > "this new language that's going to take 20% off our development costs because [it] [will take care of stuff they used to have to manage with reviews, testing and, you know, good SW engineers.]"

        Wasn't this basically the argument for all the scripted, and even type-free languages? Python? Ruby on Rails? PHP? at least / to start with. Even, "Semantic Code."

        Then maintaining and using them becomes nightmare-ish, unless you're a True Believer. They're relegated to small projects, because they're not suited for large applications. See also, Microsoft designing Typescript; Python's developer acknowledging that type-free languages are great for getting things done -- but not so great in large applications where you need to interact with other people's creations (in the same language).

        1. GNU SedGawk Bronze badge

          I kind of buy scripting languages, quite often for some small task I need something to sit on a message bus consuming or producing events, there is no advantage to doing that in any particular language other than library support.

          I think a lot of the noise settles once you have a base template repository with tests / build / deployment to start from.

          So if you are starting from something that all ready has a test suite, already does the sane thing, it's easier to have low friction.

          In a scripting language that might be a few less files, but even once you correct for that, there is a size that static typed languages start to help but only for proper code, not things where efficiency is laughably unimportant.

          I rather like Ruby because it's easy to throw together something tested and bolt on a nice native extension to do the heavy lifting.

      3. Bluck Mutter

        MVP...it's right there in the name..Minimum

        "Rust might appeal to companies who think they can shorten or even skip some bits of the software development process because Rust will take care of stuff they used to have to manage with reviews, testing and, you know, good SW engineers."

        Indeed.... combine this attitude with MVP and [FR]Agile and we have a trifecta of "goodness".

        Time to market is king now (just look at the shit show of half baked stuff coming from MSoft like Recall)...so whatever time can be shaved in whatever way keeps the exec's bonuses flowing.

        While there have been many reasons for changes in software development methods over the years (I am old so have seen it all...like Jackson Structured programming from the 70's) but I think (like many other things) the Internet changed it all.

        In the old days, sending a patch meant mailing a physical media so "time to repair" was long...thus you had to release a Maximum Viable Product.

        Now if you screw up in your rush to release an application/app **...no issue...just send a patch that is auto installed in minutes via the Net...so no need to invest any up front time in getting it right the first time.

        Bluck

        *** given I am old an application is different from an app...SAP is an application, tiktok is an app

  4. Locomotion69 Bronze badge

    Only if

    'sudo' is a symlink to sudo-rs, so the former sudo with said vulnerabilities is not used - not even by accident or on purpose.

    1. m4r35n357 Silver badge

      Re: Only if

      Why complicate matters with a symlink? Just call the sudo-rs executable "sudo".

      This is how the situation is dealt with everywhere else . . .

      1. Anonymous Coward
        Anonymous Coward

        Re: Only if

        Why complicate matters with a symlink? Just call the sudo-rs executable "sudo".

        At a guess it's actually two symlinks using alternatives(8)

        1. m4r35n357 Silver badge

          Re: Only if

          My point is the OP says it should NOT be an alternative!

  5. rgjnk Silver badge

    Training wheels

    Not sure the blinkered focus on 'memory safety' is worth the rest of the compromises of this current obsession with Rust.

    Your inability to design, implement and test adequately to produce robust code to eliminate a subset of non-inherent issues is not a solid justification, any more than your inability to ride a bike would be reason to force training wheels on everyone.

    And I especially hate it when people try to mandate their current favorite solution as the One True Answer rather than properly defining the problem and leaving it open how to reduce it.

    It's not like Rust is exactly perfectly robust (or even viable) in all scenarios either.

  6. williamyf Bronze badge

    Before any one complains about sudo-rs being MIT

    and that this will destroy the GNU-GPL-Linux concept, please be aware that the GNU crowd crowd are FREE (as in FREEDOM) to fork and re-license this code as GPL whenever they want.

    Meanwhile, one is NOT FREE to fork GPL code and re-license as something else.

    Therefore, if the GNU crowd is worried about rs-sudo, or toybox, or uutils being in certain linux distros, better get forking, re-licensing and mantaining...

    My toughts, licenses are just tools, there are right tools for the right job. The only ones who have a say on the license of a project are the people/entities who start said projects. If you do not like the license either fork and re-license (if possible) or re-implement.

    The best example is Toybox. Busybox was created as GPL. One of the original implementers of Busybox tought a BSD type license woud be more amenable for the main use case of busybox (embeded systems) so they re-implemented from scratch with a permissive licence. No language change, no nothing.

    1. Anonymous Coward
      Anonymous Coward

      Re: Before any one complains about sudo-rs being MIT

      The only reason to downvote this would be if you are in a GPL cult.

      Their mantra: "No-one can dare point out the flaws with the GPL God!"

    2. boblongii

      Re: Before any one complains about sudo-rs being MIT

      "The only ones who have a say on the license of a project are the people/entities who start said projects."

      I agree - if people are stupid enough to work for Apple for free then that's their lookout. I'm not, so I'll never use the BSD license for my own output. The richest company in the world can pay their fucking developers themselves.

      1. Jamie Jones Silver badge

        Re: Before any one complains about sudo-rs being MIT

        That's not the way it works.

        The people who use the BSD license want the best software to be used as universally as possible - this is especially true for standards - if companies were forced to write their own, they'd invariably screw up on the spec, and their messed up implementation may even become the defacto standard because of it.

        quote: https://klarasystems.com/articles/use-bsd-licensing-for-next-open-source-project/

        The permissive nature of the BSD license has led to it being preferred for network standards and reference implementations, because of its compatibility allowing inclusions in both open source and commercial software.

        By the way, have you heard of LLVM/Clang, or CUPS? open-sourced by apple: there's a fuller list here: https://opensource.apple.com/projects/

        Finally, just curious, how do you feel about people taking BSD licensed projects and forking them as GPL? Seeing as you could argue it's someone using BSD software, but not contributing back to it (i.e. their improvements are GPL only) do you refuse to use them, out of a similar moral principle?

      2. raindog

        Re: Before any one complains about sudo-rs being MIT

        Sorry mate, but that ship has sailed. Before too much longer, the only GPL-licensed part of your typical Linux distro will be the kernel itself. It's been the clear trend for quite a while.

  7. williamyf Bronze badge

    In my youth I learned many languages

    BASIC, COBOL*, RPG-II, PASCAL and C** (not bad for an electronics engineer)

    Got decent enoogh in C to become a teacher's assistant.

    Languages are tools, there is not a "true tool". One should do an excersice:

    If Mr. Torvads were starting the Linux Kernel today ¿would he use rust? ¿Zig? ¿C? ¿Erlang?

    IMHO, rustifying the Kernel Loadable Modules (drivers) and userland is not that bad.

    * The big advantage of COBOL in that era was that, if you showed your program to a non-techie (say, an accountant or a lawyer), the language was verbose and close to natural english enough, that the person could understand it enough to validate that the business processes/logic/rules and legal issues were correctly represented. They could not write it themselves from scratch, they could not maintain it, the could not detect sublte errors, but understand enough to give you the A-OK that the relevant lawer/accounting things were done correctly.

    ** ¿Does AWK and shell scripting count as languages?

    1. Jamie Jones Silver badge

      Re: In my youth I learned many languages

      I love AWK. I write lots of stuff in it.

  8. Dan 55 Silver badge
    Alert

    sudo

    Now there's a command you want to experiment with.

  9. Doctor Syntax Silver badge

    "Sudo is a command-line utility on Unix-like systems that allows authorized users to run commands with elevated privileges, typically as root" without the safeguard of an additional password. It fails Saltzer and Schroeder's separation of privilege criterion: https://en.wikipedia.org/wiki/Saltzer_and_Schroeder's_design_principles

    1. spuck

      One of the reasons (perhaps the biggest reason) to use sudo is to avoid the need to divulge an additional (usually root's) password.

    2. Anonymous Coward
      Anonymous Coward

      See "doas" as a leaner alternative

  10. Anonymous Coward
    Anonymous Coward

    The rust port pulls in so many dependencies. Hundreds! There is no way this can be safe.

    Plus it is mostly just bindings ontop of C code, again, this is not going to be verifiably safe.

    1. Androgynous Cupboard Silver badge

      Hundreds?

      For the millionth time, stop exaggerating.

      1. Zuie

        Re: Hundreds?

        There's something so hilarious about telling someone to not exaggerate "for the millionth time". Lol

        1. JamesTGrant Silver badge

          Re: Hundreds?

          Whoosh

    2. Bluck Mutter

      Have you tried Python?

      So I am retired now and have been buggering around (2 years now) writing some relatively complex software (in C++ on Linux) for long term personnel use.

      One thing (two actually!!) I did need which I wasn't prepared to write was Speech to Text and Text to speech.

      So you hit the web, look around and try different applications in this space.

      Many are written in Python so out of interest (in case they are The One) you install them.

      Talk about a shit show of stuff downloaded from unknown sources to make it run. Not 100's but 10 to 20 which means the application will not run in a year or two once some dependency goes dead.

      I managed to find both a STT and TTS application written in C/C++ that are totally reliable (esp STT), standalone, can be recompiled without need for any outside resource and in the case of STT, the model is local and doesn't make use of some cloud resource.

      Some were in rust and had a similar profile...downloading stuff from places unknown,

      What I like, being an old timer, are languages were the complete set of features/functions exist locally (even if some utility/library initially were download/compiled). This means you are isolated from 3rd parties.

      Bluck

      1. Blazde Silver badge

        Re: Have you tried Python?

        There's nothing stopping you downloading libraries from repositories and keeping them without any reliance on 'cloud' (aka the internet *). Rust's cargo for example has the 'vendor' command, although there are other approaches too. There's also a very strict policy against deletion on crates.io, so no they won't disappear in a year or two just because a single dependency dies:

        Crate owners can delete their crates under certain conditions: the crate has been published for less than 72 hours, or the crate only has a single owner, the crate has been downloaded less than 500 times for each month it has been published, and the crate is not depended upon by any other crate on crates.io. If these conditions are not met, the crate will not be deleted.

        (*) It's no different to downloading a C++ library from a random .edu website. Of course you keep it locally because the postgrad who published it inevitably loses their webspace and ceases to care about the library a few years later.

  11. BinkyTheMagicPaperclip Silver badge

    I note they're not mentioning OpenBSD

    OpenBSD instead tends to use doas, which completely threw away the tens of thousands of lines of sudo code and wrote an alternative (in C) to handle the case of running one command as another user, which is what people use sudo for most of the time.

    Seems to me using the Unix philosophy, it'd be better to use a set of smaller commands that are easy to audit the code for, than maintain one bloated codebase with functionality that frequently goes unused by most people.

    1. idoak

      Re: I note they're not mentioning OpenBSD

      There is a port of doas (OpenDoas) available for linux as well, mind.

  12. Gary Stewart Silver badge

    Rust

    After 35+ years in programming rust was the first language in many years that I found interesting enough to look into. My main complaint about rust at this time is the lack of a standard for the language with some official mechanism to suggest improvements. I recently read that they are going (?) to use a standard developed by a company that uses rust in an embedded environment as a base. So I might soon need to pull out my rust books and get busy learning it again.

    That said using rust to improve sudo does not really gain much in the way of security. Most distros that use sudo to replace su and root configure it as username ALL=(ALL) ALL which gives the user the ability to run any program that root can run. So the ability to break into that users account (they use the same password) makes the memory safety of rust a mute point. sudo was never designed to be a replacement for su. It's purpose was to allow root to give access to a limited number of programs to trusted admin assistants for administrative and debug purposes. The key words being limited and trusted. The only security advantage of sudo configured as described over su is that sudo will automatically log out after a period of no activity and su must be logged out manually,

    1. Steve Graham

      Re: Rust

      The ALL business for sudo is a feature of Ubuntu and its derivatives. (Not used in the original Debian.) I've never liked it.

    2. Anonymous Coward
      Anonymous Coward

      Re: Rust

      No, no, no. I've read support forums. Sudo is there to make programs work when they won't on your normal account.

      What's the worst that could happen on a secure system like Linux?

  13. spuck

    If the C and C++ communities cannot come up with foolproof ways to meet memory safety mandates

    As long as C has pointers and lacks bounds checking, it is guaranteed that fools will continue to find a way to misuse them-- and I'm including myself in that group of fools.

    1. Claptrap314 Silver badge

      It blows my mind that after almost 50 years, we STILL don't have ready access to the C & O bits. Just add +?, -?, *?, /?, <<? already and be done with it. Oh, I know. Coercion makes that a <em>little<\em> complicated. Tough. You want it. You make it work.

  14. JamesTGrant Silver badge

    Let’s split the difference - it’s either assembly or BASH.

    Makes me happy == perfect for everyone.

    1. Dan 55 Silver badge

      That should be...

      if [[ "${MAKES_ME_HAPPY}" == "perfect for everyone" ]]; then

      1. Havin_it
        Headmaster

        I know James T did specify BASH, but you'd be more perfect for everyone with single '[' and '='. The doubles are ... bashisms.

        (Sorry if that was the joke)

        1. Dan 55 Silver badge

          I think it was originally a kshism and zsh also understands it. I can't be doing with the POSIX syntax.

  15. LybsterRoy Silver badge

    I just love these religious discussions. NOw if I can only squeeze climate change and brexit in .....

  16. jsmith84

    Who cares? (either ways!)

    I read the thread "Another day, another attempt to force this on us"...

    Just by title, it seems that some people are offended by the fact the machinery of sudo was rewritten in Rust.

    When buying a Xbox series S, nobody cares that the internal might have changed between the version of July 2024 and January 2025. People are still buying a console with the same power and same features, and do not realise manufacturers constantly optimise what is under the hood.

    Here, you just have to use sudo exactly like you use it before, so why do you care what the source language was for this version? (If Ubuntu never told anyone, nobody would have realised)

    I have been programming in C and C++ for over 30 years now, and have been programming in Rust too. There are lots of things I really dislike in Rust, among which the borrow checker being way to pedantic compared to what would be strictly necessary (it's a long discussion I am not going to have here) and some of the library throwing exception because it does not like cycling graph detected only in certain condition (std::Rc) which make me chuckle as the safety aspect (and yes, don't get me started which the stupidity of integer overflow checked in Debug only as default behaviour... shared variables in different threads).

    However, Rust is good for idiots for sure, but I must admit it will enforce a lot of safety by design (to the expense of speed for people like me) and has features making your life easier (and some making your life harder for sure).

    One has to choose your fight and also decide if moving to Rust enable some fixes you could not have by simply fixing an existing behaviour (value benefit analysis). Sometimes, using Rust is based on dogma, and yes, it can give the feeling of "another attempt to force this on" some people.

  17. Anonymous Coward
    Anonymous Coward

    IMHO

    Reading the announcement and the motivation behind uutils/sudo-rs makes it clear than nobody care much about Rust, only that they don't want to afford another big security breach because of the infamous "memory unsafety"-ness.

    In 2000s, sudo would have been rewritten in Java or even in Go in 2010s if "memory safety" was the buzzword at this time. But nowadays, they want a "memory safe" (for what it means) tool, and since they still need devs to do it, they need to find a language with some people with enough experience.

    It could have been worse, like writing it in Crystal or Carbon or any other esoteric language where the number of devs in this World is less than the number of products without AI theses days.

    So, what theses $B company need to prevent an hypothetical CVE, and Rust is part of the solution. And since devs can learn any language (as in "well, it's just C with weird verbose syntax and C++ compile time"), they go where is money is.

    After all, Git has replaced SVN, LLVM has replaced GCC (in many tools) and devs don't code in C++ like it's 1999. Is that perfect nowadays? Nope but it's slowly evolving, as much as people care to make it better. And if it's not broken? If you boss is paying you to fix it, do fix it.

    1. Dan 55 Silver badge
      Facepalm

      Re: IMHO

      Christ, git. There's another huge mistake which is somehow orders of magnitude more popular than it should be. If you're going to choose a post-SVN distributed VCS then Mercurial or Fossil would be an improvement, but git is somehow everywhere.

      1. GNU SedGawk Bronze badge

        Re: IMHO

        mercurial deserved to die a lonely death. Fossil not tried.

        Have suffered through rational clearcase ?

        I quite liked perforce - but git bisect is a thing of beauty

        1. Dan 55 Silver badge

          Re: IMHO

          At least Mercurial doesn't let you accidentality delete the remote branch.

          git is fine if you're a kernel maintainer wanting to bring in a load of little changes from a lot of people who are outside your organisation, but in the average project where you're all developers working at a company, it just makes work more pointlessly complicated. The command line is a mess. The help makes as much sense as this. People have researched into how bad git is and put abstractions on top of git to make it usable but unfortunately further development stopped.

          (Didn't downvote.)

          1. GNU SedGawk Bronze badge

            Re: IMHO

            For the average developer - they just - git add . - and comment nonsense, so it doesn't matter what source control you give them.

            But for git add -p and producing a nice patch series is really good for a decent workflow in a company with good platform teams supporting decent application teams, all of whom are working at their own cadence.

            The UX is utterly hostile to people who are not living in a terminal and eating patches for breakfast. But It's useful when you learn it properly and it's amenable to decent configuration.

            git ll is a lot nicer once your ~/.gitconfig has

            [alias]

            ll = log --abbrev-commit --graph --pretty='format:%C(yellow)%h%Cblue%d%Creset %s %C(white) %Creset %aN GPG: %G?'

            lu = ls-files --others --exclude-standard

            it's quite hard to delete a remote branch by accident, but I agree with you, the tooling is not as friendly to people as it could be, largely because its a patch based workflow that it makes possible.

            It's great for making the perfect series of clean reviewed polished patches implementing a feature as if written all at once flawlessly.

            Instead people preserve every edit and bump which ends up slowing down clones. The problem as I see it being an opinionated person, is that these tools are opinionated about particular workflows, and every step outside of that workflow imposes a burden.

            Git is a victim of it's own success.

  18. Andrew Mayo

    This is obviously an impassioned debate. The issue here is that some developers work in multiple languages and regard coding as a means to an end. They learn enough of each language to be effective but they do not obsessively follow every single enhancement.

    Others devote enormous time and effort perfecting skills in a single language and then take pride in using its more abstruse features to write code which is often elegant in an abstract sense but hard to follow for those with more generalist skills.

    For these people their code defines them - even though the hard reality is that nobody else gives a damn as long as the darn thing runs and performs well and doesn't have any obvious bugs.

    As someone who has worked in assembler (x86/IBM 360) COBOL, FORTRAN, C, C++, C#, Java, Go, Python and several other languages I am at this stage far from being a Rust expert. When it comes to C++ code I tend to use the STL and write in an idiom that probably resembles C# more than anything else, because I can reason about that code fairly easily. That said, C++ is full of fish-hooks, I recall hitting an issue where a Unicode string kept growing because I hadn't 'imbued' it with UTF-8-ness or something silly like that.

    C++ templates - and worse - template templates - result in compile-time errors which can be absolutely arcane unless you really understand the inner workings of the compiler. C++ is a bunch of rivets flying in close formation. Yes, it works. Yes, if you are extraordinarily careful you can write safe code in it. But that was argued about assembler as well, back in the time. High-level languages? Hmmph. Never gonna work in my memory-constrained environment!.

    Here's my take on what will happen.

    On Planet Zorg, which is where those C++ obsessive types live, the debate will rage on for a couple of decades, diminishing only as the participants retire or become unemployable because their skills are outdated.

    In the real world, where the rest of us live, Rust slowly and inexorably replaces more and more critical infrastructure over time. Yes, there are issues with crate functionality, these will be addressed over time. But the fundamental design; enums done properly, traits, etc. is very elegant.

    I can see transpilers being written that will also be able to deduce lifetimes and produce Rust code from C++ code. This would be a far better use of time and effort than trying to patch up a language which is reaching the end of its life.

    I do appreciate the 'sunk cost' many C++ experts have with regard to the language, which is why some of the debate regarding the Linux kernel is so heated. But Torvalds doesn't live on Planet Zorg so immediately he can see that, pragmatically, it makes far more sense to embrace Rust and not defend C++. He's right. As someone said once. "You can bet that the last buggy whip manufacturer made damn good buggy whips". I'm afraid the era of the horse is drawing to a close. Time to move on, and if the C++ aficionados redirected their fury to rectifying shortcomings with Rust crates, that'd be far better for everyone. Otherwise, it's a case of 'old man shouts at cloud' chaps!

    1. GNU SedGawk Bronze badge

      You kind of get it but miss the point.

      I'm not that interested in which language is used to do a task. I'm happy for you to run whatever code you like inside the container for deployment. Everything needs tests/CI/CD so it's not important to me.

      I am interested in security and secure systems, since that's directly part of my job. I'm also interested in understanding the performance of the software.

      It's that last point which brings the rust users into conflict - It's difficult for someone to accept that their code is irrelevant in making secure systems, the contribution to the overall picture is low enough, that you can code in any language more or less with the same results.

      Now when you want auditable systems with predictable behaviour, that's when C++ and C shine. The data access patterns are explicit. The entire ecosystem support is available for resilience.

      Instead - we're asked to accept some restricted choices, so zealots can push a single source compiler on us.

      If you can do "defeating trusting trust" as table stakes, the word secure doesn't apply to you.

    2. Richard 12 Silver badge

      The Linux kernel is in C

      Not C++. That's the thing. They're different languages.

      There are several design decisions in Rust that mean it cannot ever safely replace C++.

      Rust can however replace C for small standalone projects - and if they get around to fixing the glaring holes before another language-du-jour does, then it may eventually handle larger C projects.

      If you're looking for a C++ replacement, it might well be Swift - though realistically it's far more likely to be modern C++.

    3. Dan 55 Silver badge

      Presumably those advocating for Rust replacing C++ have never written a program which requires object orientation... no GUI, no objects representing underlying data, nothing of that sort?

POST COMMENT House rules

Not a member of The Register? Create a new account here.

  • Enter your comment

  • Add an icon

Anonymous cowards cannot choose their icon

Other stories you might like