home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.programming      Programming issues that transcend langua      57,431 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 57,399 of 57,431   
   David Brown to Dan Cross   
   Re: Rust vs Hype (was Re: Informal discu   
   02 Aug 25 17:47:40   
   
   [continued from previous message]   
      
   null pointer dereferences.  I do not recall ever having had a null   
   pointer bug in any C code I have written over the last 30+ years.  I   
   have occasionally had other pointer-related errors, typically as a   
   result of typos and usually found very quickly.  These kinds of mistakes   
   are avoided with due care and attention to the coding, appropriate   
   testing, sensible coding standards, and other good development   
   practices.  Good tools can help catch problems at compile time (such as   
   compiler warnings about uninitialised variables, or extensions to mark   
   function parameters as "non-null").  They can also catch bugs quickly at   
   runtime, such as using sanitisers.  I am a big fan of any language   
   feature that can make it more difficult to put bugs in your code (the   
   power of a programming languages mainly comes not from what it allows   
   you to write, but what it stops you from writing).  But things like null   
   pointer bugs are not a symptom of C programming, but of poor software   
   development - and that is language independent.   
      
   3. Alternative existing and established languages already provide   
   features that handle this - the prime example being C++.   
      
      
   >> I also see little in the way of comparisons between Rust and modern C++.   
   >   
   > Really?  I see quite a lot of comparison between Rust and C++.   
   > Most of the data out of Google and Microsoft, for instance, is   
   > not comparing Rust and C, it's actually comparing Rust and C++.   
   > Where Rust is compared to C most often is in the embedded space.   
      
   I work with embedded development, so maybe that colours my reading!   
      
   >   
   >>   Many of the "typical C" bugs - dynamic memory leaks and bugs, buffer   
   >> overflows in arrays and string handling, etc., - disappear entirely when   
   >> you use C++ with smart pointers, std::vector<>, std::string<>, and the   
   >> C++ Core Guidelines.  (Again - I am not saying that C++ is "better" than   
   >> Rust, or vice versa.  Each language has its pros and cons.)   
   >   
   > And yet, experience has shown that, even in very good C++ code   
   > bases, we find that programs routinely hit those sorts of   
   > issues.  Indeed, consider trying to embed a reference into a   
   > `std::vector`, perhaps so that one can do dynamic dispatch thru   
   > a vtable.  How do you do it?  This is an area where C++   
   > basically forces you to use a pointer; even if you try to put a   
   > `unique_ptr` into the vector, those can still own a `nullptr`.   
   >   
      
   Sure, there are still occasions when you need raw pointers in C++.  It   
   is far from a "perfect" language, and suffers greatly from many of its   
   good ideas being add-ons rather than in the original base language,   
   meaning the older more "dangerous" styles being still available (and   
   indeed often the default).  But just as you should not need raw pointers   
   in most of your Rust programming, you should not need raw pointers in   
   most of your C++ programming.   
      
   >> So while I appreciate that comparing these two projects might be more   
   >> useful than many vague "C vs. Rust" comparisons, it is still a   
   >> comparison between a 10-20 year old C project and a modern Rust design.   
   >>   
   >> The most immediate first-impression difference between the projects is   
   >> that the Rust version is sensibly organised in directories, while the C   
   >> project jumbles OS code and user-land utilities together.  That has,   
   >> obviously, absolutely nothing to do with the languages involved.  Like   
   >> so often when a Rust re-implementation of existing C code gives nicer,   
   >> safer, and more efficient results, the prime reason is that you have a   
   >> re-design of the project in a modern style using modern tools with the   
   >> experience of knowing the existing C code and its specifications (which   
   >> have usually changed greatly during the lifetime of the C code).  You'd   
   >> get at least 90% of the benefits by doing the same re-write in modern C.   
   >   
   > Not really.  rxv64 has a very specific history: we were working   
   > on a new (type-1) hypervisor in Rust, and bringing new engineers   
   > who were (usually) very good C and C++ programmers onto the   
   > project.  While generally experienced, these folks had very   
   > little experience with kernel-level programming, and almost none   
   > in Rust.  For the OS bits, we were pointing them at MIT's course   
   > materials for the 6.828 course, but those were in C and for   
   > 32-bit x86, so I rewrote it in Rust for x86_64.   
   >   
   > In doing so, I took care to stay as close as I reasonably could   
   > to the original.  Obviously, some things are different (most   
   > system calls are implemented as methods on the `Proc` type, for   
   > example, and error handling is generally more robust; there are   
   > some instances where the C code will panic in response to user   
   > action because it's awkward to return an error to the calling   
   > process, but I can bubble thus back up through the kernel and   
   > into user space using the `Result` type), but the structure is   
   > largely the same; my only real conceit to structural change in   
   > an effort to embrace modernity was the pseudo-slab allocator for   
   > pipe objects.  Indeed, there are some things where I think the   
   > rewrite is _less_ elegant than the original (the doubly-linked   
   > list for the double-ended queue of free buffers in the block   
   > caching layer, for instance: this was a beautiful little idea in   
   > early Unix, but its expression in Rust -- simulated using   
   > indices into the fixed-size buffer cache -- is awkward).   
   >   
      
   I can certainly see that some things are more inconvenient to write in   
   C, even in modern C standards and styles - Rust's Result types are much   
   nicer to use than a manual struct return in C.  (C++ has std::expected<>   
   that is very similar to Result, though Result has some convenient   
   shortcuts and is much more pervasive in Rust.)   
      
   > The Rust port did expose a few bugs in the original, which I   
   > fixed and contributed back to MIT.  And while it's true that the   
   > xv6 code was initially written in the mid 00's, it is still very   
   > much used and maintained (though MIT has moved on to a variant   
   > that targets RISC-V and sunsetted the x86 code).  Also, xv6 has   
   > formed the basis for several research projects, and provided a   
   > research platform that has resulted in more than one   
   > dissertation.  To say that it is not representative of modern C   
   > does not seem accurate; it was explicitly written as a modern   
   > replacement for 6th Edition Unix, after all.  And if it is not   
   > considered modern, then what is?   
   >   
      
   Modern C would, IMHO, imply C99 at the very least.  It would be using   
   C99 types, and it would be declaring local variables only when they can   
   be properly initialised - and these would often be "const".  It would be   
   using enumerated types liberally, not a bunch of #define constants.  It   
   would not be declaring "extern" symbols in C files and other scattered   
   repeated declarations - rather, it would be declaring exported   
   identifiers once in an appropriately named header and importing these   
   when needed so that you are sure you have a single consistent   
   definition, checked by the compiler.  It would not be using "int" as a   
   boolean type, returning 0 or -1, or when an error enumeration type would   
   be appropriate.  It would be organised into directories, rather than   
   mixing the OS code, build utilities, user-land programs, and other files   
   in one directory.  Header files - at a minimum, those that might be used   
   by other code - would have guards and include any other headers needed.   
   Files would have at least a small amount of documentation or   
      
   [continued in next message]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca