* Posts by ssokolow

123 publicly visible posts • joined 3 Feb 2021


Sleuths who cracked Zodiac Killer's cipher thank the crowd


Or they ask what the heck IPA means and are given a beer.

Rust developers at Google are twice as productive as C++ teams


Re: I wonder...

In Rust, the general answer is "If you don't recognize the syntax, assume it's from Ocaml". Rust is more or less a GC-less ML derivative wrapped in some borrowed C++ syntax to make it friendlier. (Right down to rustc originally having been written in Ocaml.)

In that specific case, 'a is the Ocaml equivalent to <T>, because, abstractly, lifetimes are a special kind of generic type parameter.


I finally got around to watching the talk itself. The question wasn't "How confident are you that your code is correct?", it's "How confident do you feel that your team's Rust code is correct?"

...that is, it's asking "Having experienced reading and reviewing your teammates' code, do you feel more or less confident that they've done it properly when they write in Rust?"

Still not saying whether they did do it properly, but Rust appears to make reviewers feel better about what they're reading from other people at least.


Re: "Testing Code"

Or, as Dijkstra put it, "Program testing can be a very effective way to show the presence of bugs, but it is hopelessly inadequate for showing their absence."


Re: Have to wonder....

"I have to wonder whether the increase in programmer productivity is in part due to much smaller Rust teams than the "huge" C++ teams."

I hope not. Rust's raison d'etre is to extend the type system to be able to effectively act as a lockout-tagout system for programming to limit the ability for defect rates to climb as team sizes do. (i.e. to protect you from changes you didn't see someone else make and vice-versa and to minimize the need to reason globally about the codebase's behaviour.)


Re: confidence

"Call it "Csafe" or something. It can compile C code but will include bounds checking and all that guff to make it a little bit slower but a lot safer. After all, C++ exists and didn't replace C..."

Various efforts have been made and even more proposed over the years. (eg. the splint linter has been able to enforce a surprisingly large subset of what Rust can do via annotations for 20 years now and I remember seeing at least one mentioned on LWN years ago) ...the problem is getting actual interest from programmers.

Hell, some of them, like Cyclone, were direct inspirations for Rust.

What really makes Rust special is successfully achieving critical mass.


Re: Rust really is easier to write and maintain

They could have meant any of three things by that:

1. Rust isn't good for making GUIs because the ecosystem is particularly immature there.

2. Rust isn't good for making GUIs because Rust doesn't do classical inheritance and the big-name widget toolkits tend to be based on that type of OOP, so the bindings aren't as nice-feeling. (See, for example, how gtk-rs does it.)

3. Rust isn't good for making GUIs because existing toolkits have their own conceptions of object lifecycles which need to be adapted in any bindings written.

All three are true to some degree... but then I'd also say that Rust isn't the best for the niche that the Django framework for Python fills, because it's got a gigantic ecosystem of reusable components already written.

Keep an eye on the Iced toolkit. It's what's System76 is using to develop the COSMIC desktop for Linux.

Microsoft seeks Rust developers to rewrite core C# code


Re: JavaScript "Performance"

You are aware that an application server will want to service more than one request simultaneously, right? Wasted cycles are wasted cycles... especially in this era of "bill for every CPU cycle" cloud services being popular.


Re: Microsoft seeks Go developers to rewrite Rust core code

You're probably thinking of this Discord Blog post: Why Discord is switching from Go to Rust


Re: Rockstar

Whenever I see a hyperlink with some variation on "this" as the text, I assume Rick Astley will be on the other end and don't bother.


Re: Indeed

In Rust's case, it doesn't automatically insert mutexes. It instead says "Hold up. Did you mean to share this? If so, you'll need a mutex."

...because, sometimes, what you really want is to fix the bug that's causing it to keep a reference, so you can just send it to the other thread without sharing it.

Otherwise, you wind up with things like those JavaScript "something, somewhere, is still holding this alive when it shouldn't be" memory leaks.


Re: Efficiency

Which is what things like stack allocation are for, along with APIs designed to make reuse of heap memory without handing it back to malloc easy.


Re: JavaScript "Performance"

Plus, the elephant in the room with all these "high-level, in the 'let me focus on the business logic instead of machine details' sense" languages... it's very easy to fall off the fast path.

A statically typed GCed language like C# or Go will give the compiler more ability to say "Whoa, hold up there. Are you sure you meant that?" and something like Rust, C, or C++, where you explicitly choose things like inline/stack allocation vs. unique heap pointe vs. reference-counted heap pointer instead of letting automatic allocation handle it will do so even more.

(To be honest, my biggest complaint about Rust is that LLVM doesn't give them the APIs they'd need to viably make things like "this optimization used to get applied and now it doesn't" into a compile-time error.)



Here's the most recent This Week in Rust featured quote:

The sheer stability of this program is what made me use rust for everything going forward. The social-service has a 100% uptime for almost 2.5 years now. It’s processed 12.9TB of traffic and is still using 1.5mb of ram just like the day we ran it 2.5 years ago. The resource usage is so low it brings tears to my eyes. As someone who came from Java, the lack of OOM errors or GC problems has been a huge benefit of rust and I don’t ever see myself using any other programming language. I’m a big fan of the mindset “build it once, but build it the right way” which is why rust is always my choice.

-- https://www.reddit.com/r/rust/comments/1ach3ir/what_were_some_of_the_first_useful_applications/kjuhaox/

Memory safety isn't the only thing under the heading of "predictability" that Rust is good at. Implicit control flow is also a big one.

For example, NPM experimented with doing something similar with one of their Node.js-based services and kept the rewrites because, while they performed about the same as the hyper-optimized mature JavaScript codebase doing things Node.js had been tuned to be best at, they eliminated the flood of uncaught exceptions they were constantly working to track down in their log files.

Gtk 5 might drop X11 support, says GNOME dev


Re: Opposites

I think the word you're looking for is "ModeLines".

(Source: I had to do it within the recent past to get 1080p working on an HDTV with broken EDID tables and I'm pretty sure the syntax was the same as it was when I first got into Linux in the 2000s. I still vaguely remember the two different iterations of "make me an XFree86 config" tool that we went through before finally getting autoconfiguration with Xorg and X11R7.)

Microsoft is busy rewriting core Windows code in memory-safe Rust


Re: CreateWindowEx()

Time to see where the Petzold and Richter Win32 programming books are. (Largely outdated now, but those were probably the most useful books on programming I have ever encountered: Charles Petzold on the GDI and Jeffrey Richter on the Win32 API).

Thanks for those recommendations. Back when I was young, I jumped from QBasic to Visual Basic 6 to wxPython to Linux, bypassing the actual Win32 APIs and, now that I'm tooling up and kitting out to do some of the hobby programming I lacked the tools for back then, I've been looking for some good MFC, ATL, and COM materials as a lead-up to Dino Esposito's Visual C++ Windows Shell Programming.

(Utilities and UI enhancements have always been my thing. On the Windows 3.1 hobby programming side, one of the big things I need to do is figure out how those "custom icons for Program Manager" things work. So far, my best guess is that, when I start investigating, I'll discover that they're hooking the event loop and rewriting the requests to build and modify the UI in a way conceptually similar to something like Proxomitron or Privoxy for HTTP.)


Re: My preferred GUI library is...

It depends. In the era of Qt 3.x and GTK+ 2.x, it was a good all-round choice.

Now, with GTK 3 and 4 apps being increasingly alien on non-GTK desktops as non-negotiable GNOME-isms creep into the toolkit, it depends on whether I care more about making something feel Windows-native or KDE-native (I'm a KDE user).

Here's hoping the rumblings I remember hearing about a revival of the wxQt backend bear fruit.


Re: "all of these expensive checks are in the debug build"

But also the Rust bindings could benefit from this too.

GTK is a poor example for this because they already have their GIR (GObject Introspection) interface definition language, which provides enough memory safety information that PyGObject is able to dynamically load the GIR file and synthesize Python bindings at runtime.

My understanding is that gtk-rs is already also relying on GIR.


Re: "all of these expensive checks are in the debug build"

but if C is made more safe, it might just be enough to avoid having to invest in writing your own FFI code to call into native system libraries (a process involving a lot of unsafe code!), or pulling in potential technical debt in terms of bindings from crates.io (and hoping their unsafe sections remain well maintained).

I'm not sure how C could be made safe enough for that without becoming "Rust, but with less ergonomic syntax" but, supposing it can get part of the way there, it'd certainly make writing Rust FFI less unsafe, which would be nice.

(Rust FFI is unsafe because C doesn't provide enough information about its invariants for the Rust compiler to guarantee that your FFI code is memory-safe. The more information C code can offer to a tool like bindgen, the closer to safe Rust the resulting generated code can be.)


My biggest concern is the same as it is for Linux kernel using Rust: garbage collection

(it does not belong in code ANYWHERE and is so often abused nowadays that mail readers and browsers left running will ultimately allocate EVERY FREE BYTE OF RAM, causing performance stutfers when you switch to something else, because 'hang onto RAM' for THAT is the ONLY application worth running on YOUR computer, at least in the devs' less than brilliant minds)

Rust doesn't have a garbage collector and the only garbage collection it has is the same kind C++ has: an opt-in reference-counted pointer type (std::shared_ptr in C++). Ownership and borrowing is just C++-style RAII with reliable compile-time support for rejecting code that would create dangling pointers, no legacy array type that decays into pointers, and gating things like pointer arithmetic behind an unsafe keyword. (Something that can't be feasibly retrofitted onto C++ because of the vast swaths of existing code lacking the necessary information about the programmer's intent.)

What's more, the language is designed so that using reference counting is uglier than not using it, so programmers are nudged toward single ownership and architectures where it's hard for accidental data lifetime extension to lurk.

...OK, technically, Rust has two reference-counted pointer types. It splits std::shared_ptr into Rc (no atomics) and Arc (atomics) and makes it a compile-time error to send an Rc handle to another thread rather than switching use of atomics on or off based on whether libpthread was linked, so you've got more control than in C over whether you're taking the performance hit of using atomics.

(That's also not magic. Things which are safe to send to other threads implement the Send trait (interface), compound data types automatically implement Send if all their members do (but you can opt back out), and APIs for sending stuff to other threads impose a Send requirement on their arguments.)


Re: This doesn't mean you should convert your app to rust

None of this is any reason to invent a whole new language. There may be other reasons to use Rust, but every reason I’ve been given so far, borrow-check included, could be and *is* implemented by some compiler, on top of ANSI C, without rip-and-replacing the language.

To me at least, Rust's greatest strength is unavoidably tied to it being a new language... the requirement that code be annotated with richer information about what invariants the compiler must uphold.

Retrofitting this has been tried with C and C++ on various occasions in the form of tools like splint, but they failed to get uptake. In Rust, they manage to get people to accept that by clean-rooming a syntax for native code that makes it less onerous than if retrofitted onto C or C++, and by making it part of the process of writing bindings, akin to TypeScript definition files.

That aside, C would also look very different if you extended it to have as rich a type system as Rust. Rust is closer to being an ML-family language disguised in a coat of C++ syntax, and one of its biggest strengths is how many invariants you can encode in the type system, to be proven at compile time.

Dijkstra was actually arguing for stronger type systems and more formal proving when he wrote this:

Program testing can be a very effective way to show the presence of bugs, but it is hopelessly inadequate for showing their absence.


Re: This doesn't mean you should convert your app to rust

1. It's recommended that you use the iterator APIs where feasible. They only need to check the array length once (same as with an optimal C for loop) and the API is designed so that going out of bounds is prevented at compile time without additional checks.

2. ReadySet wrote a blog post named How much does Rust's bounds checking actually cost? where they tried compiling their database engine with a version of the Rust toolchain that had been patched to remove the bounds checks and found no significant difference, indicating that, at least in their codebase, CPU branch prediction and memory latency were making bounds checks zero-cost.

3. Rust's assert remains present in release builds (it's debug_assert that's equivalent to C's ASSERT) and, if you assert the length of the array at the beginning of the relevant code, it serves as a hint to the optimizer to strip out the bounds checks in the indexing operations. This effect can also be achieved by iterating in reverse.

4. If you profile your code and actually find bounds checks in a hot loop being significant, there's the get_unchecked and get_unchecked_mut methods which must be called inside an unsafe block... but remember what Knuth said about premature optimization:

There is no doubt that the grail of efficiency leads to abuse. Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.

Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified.


Re: C to Rust rewrite with ChatGPT

It's not meant to be the final stage. It's intended to get you from C that compiles to semantically equivalent Rust that compiles so you can transplant your test suite and then start incrementally rewriting it to take advantage of Rust's stronger type system without a big gap where you can't be running your tests.

If GNU please: Rust support merged for the forthcoming GCC 13


> The last time we wrote about it, when covering Linus Torvalds' keynote at the Open Source Summit, we attracted criticism for, um, quoting the project's own description from that page, saying how preliminary it was.

I don't have time to read through all the comments but, if there was anything I'd criticize in that article, it'd be the lack of mention of the much more mature rustc_codegen_gcc project which works by connecting up the existing rustc frontend to GCC rather than writing a whole new one in C++.

Aside from re-bootstrapping rustc from C++ (for which mrustc already exists and where Rust-GCC probably wouldn't do any better at keeping up with the self-hosted compiler's eager use of new language features), it should serve any need you might have better. (And it's not as if Rust-GCC intends to be a completely alternative implementation. They plan to reuse Polonius, the in-development third generation of rustc's borrow checker... written in Rust, which sounds, to me, like the biggest place for "accidentally baked implementation details into the language spec" to lurk.)

> That means it's a moving target for the team working on the GCC compiler to try to hit.


> So far, there have been three "editions" of the language, which the Rust book defines as follows:

And GCC and LLVM Clang had to implement "editions" named ANSI C, C99, C11, C17, and whatever C2x will be, plus Clang having to replicate whichever GNUxx "edition" the Linux kernel is written in.

What's your point?

Heck, I find it telling that C11 seems to be the point at which C became too complex for anyone but big names like GCC, LLVM, and MSVC to implement, because all the hobby and niche compilers seem stuck at C99.

> The Rust-on-GCC project isn't the only alternative Rust toolchain being worked on. MrustC, or Mutabah's Rust Compiler, is another, being implemented in C++ and which emits, as the project page puts it, "currently very ugly C, but LLVM/cretone/GIMPLE/… could work".

...and mrustc is already complete enough to serve its purpose of re-bootstrapping rustc to prove it free of trusting trust attacks (by producing a compiler that can then compile itself and get output byte-identical to the official builds) all the way up to rustc 1.54.0 despite the rustc codebase generally being eager to use new language features.

>There's also rustc_codegen_gcc, a work-in-progress GCC code generator that uses libgccjit.

And, again, it should be mentioned that it's much further along than Rust-GCC (which should be the main thing that matters to a project like the kernel) because it works by connecting GCC up as an alternative backend to the existing rustc frontend.

See https://blog.antoyo.xyz/ for status updates on that project.

NSA urges orgs to use memory-safe programming languages


Re: Best of all

I'm not sure it'd be fair to call it "cribbing from" so much as "doing the best they can when they didn't have the resources to reinvent LLVM or the clout to force it to change".


Re: Better compilers?

Which is why people are getting fed up and turning to the "just containerize the bleeping thing" route used by things like Flatpak and Snap.

Sure, you still need to grant far too much access, but that's inherent when your browser is taking over from X.org for "OS running on top of the OS" status and the API surface for XDG Portals (the Linux equivalent to Android Intents) is still getting built out.

(eg. It's got a file/directory chooser portal that Firefox will use, but support for "When I pick this .html file, also mount the adjacent _files directory into the sandbox" is an open bug.)


Re: JavaScript: Weak Typing

...and its ancestry is clearly documented as tracing through languages like Cyclone and Ocaml, the former of which developed from 2002 to 2006 and Rust's ownership-and-borrowing paradigm is an evolutionary improvement on.


Re: Self Hosting

I usually hear it referred to as a "trusting trust attack" and one strategy for countering it is Diverse Double Compiling (https://dwheeler.com/trusting-trust/).

Since Rust doesn't yet have a second full compiler, their approach for countering that attack is:

1. Use DDC to get a trusted-to-be-clean C++ compiler

2. Use mrustc (https://github.com/thepowersgang/mrustc) to bootstrap whatever the newest version of rustc it supports is from C++. (Currently 1.54.0. mrustc is a C++-based Rust compiler meant specifically for re-bootstrapping rustc, which keeps its complexity down by just trusting that what it's compiling would pass borrow-checking under the full compiler.)

3. Use the resulting compiler to bootstrap-chain up to the current Rust compiler.

Every time it's been done so far, the hashes of the produced rustc binaries have matched the hashes of the rustc binaries that trace their lineage back to when rustc was originally written in Ocaml.


Re: Spy org says...

Rust is open-source with a very public development process, so I doubt you'll find a better candidate for not getting backdoored by the NSA.

Someone else characterized this as "the NSA has realized that trying to win at cyberwarfare by pure offense is ultimately a losing battle and has shifted to defense" and that makes sense to me.

Remember that, at the end of the day, the NSA does believe itself to be acting in defense of the U.S.A., even if the road to hell can be paved with good intentions.


Re: Better compilers?

Two main reasons:

1. The C and C++ language syntaxes don't, by default, provide enough information to the compiler. Attempts have been made to extend them on various occasions, but they're ugly and people don't use them.

2. They have huge ecosystems that don't use such annotations. When you switch languages, the act of annotating the APIs to be verifiable for correct use gets rolled into "writing bindings to the C or C++ code".

Is it time to retire C and C++ for Rust in new programs?


That's an odd way to look at it.

"C++ doesn't have a mechanism for teaching the compiler to watch your back. Therefore, it's only worthwhile to write code in a language that does if you don't have to annotate the stuff coming in from C++ at the boundary."

It reduces down to "Rust depends on OS APIs that don't encode lifetime information, which get wrapped by Rust standard library APIs. Therefore, writing code which depends on the Rust standard library is a waste of time."


That's fair.

The big reason I don't see Go, for example, as a viable alternative is that garbage collectors are solitary creatures, CPython already has one, my preference for QWidget GUIs without having to write something memory-unsafe like C++ basically means PyQt, PySide, or QtJambi, I'm not a fan of Java, and I like to write components I know I'll be able to reuse across all my projects.

(Well, that and I don't like how limited Go's support for metaprogramming and DSLs has been compared to Python, Rust, etc. and how readily you find yourself using structural rather than nominal typing. Serde, Clap, Rayon, and the typestate and newtype patterns FTW.)


Re: ... with great power comes great potential for trouble

> In 1793 the following statement appeared in a volume issued by the French National Convention as mentioned previously:


>> Ils doivent envisager qu’une grande responsabilité est la suite inséparable d’un grand pouvoir.


>> English translation: They must consider that great responsibility follows inseparably from great power.


> [...] The transcript of Lamb’s words in 1817 used quotation marks to enclose the maxim indicating that the expression was already in circulation. [...]

-- https://quoteinvestigator.com/2015/07/23/great-power/


Re: Thread Safety ?

More accurately, it only allows you to omit them in `unsafe` blocks, which are what the standard library uses to implement them, thus reducing the amount of code that needs to be audited for memory safety by an order of magnitude or more, because Rust is heavily focused on removing the need to reason globally when evaluating a codebase's correctness.

(Is this module correct? Did I design the API to enforce that correctness? ...then the compiler won't let someone else break that without using `unsafe`... and if they do, it's likely that running the code under Miri or UBSan will report that they had to violate a language invariant and invoke undefined behaviour to do it... one such example being to circumvent things that correspond to emitting the LLVM IR noalias annotations also produced by the C restrict keyword.)


Re: C++ and memory safety

Aside from a few things that haven't yet been spec'd out, like placement new, Rust is almost literally "C++, with the compiler enforcing best practices", even if it is also more of "an ML-family language in a C++ trench coat".

Rust uses the same RAII resource management techniques as C++... it just uses destructive move by default, doesn't have copy/move constructors because humans have demonstrated an inability to get those right reliably, and adds compile-time pointer validity tracking based on a model analogous to reader-writer locking.


Re: Real programmers

I prefer how Bryan Cantrill put it:

> When developing for embedded systems — and especially for the flotilla of microcontrollers that surround a host CPU on the kinds of servers we’re building at Oxide — memory use is critical. Historically, C has been the best fit for these applications just because it so lean: by providing essentially nothing other than the portable assembler that is the language itself, it avoids the implicit assumptions (and girth) of a complicated runtime. But the nothing that C provides reflects history more than minimalism; it is not an elegant nothing, but rather an ill-considered nothing that leaves those who build embedded systems building effectively everything themselves — and in a language that does little to help them write correct software.

-- http://dtrace.org/blogs/bmc/2020/10/11/rust-after-the-honeymoon/


Re: Real programmers

Nahh, they used Perl and lost the documentation for the regexes behind quantum mechanics, remember?



> I'm sure there are similar libraries to help with interfacing with GC'd languages.

Quite a few, actually:



Using Rust to write compiled extensions for GCed languages without having to manually get the `unsafe` stuff right for the C FFI in between is quite popular.


Re: One thing that make me wary of rust

There exist ones that are only a few lines long, but they're typically written by newcomers coming from an ecosystem like NPM and, on average, people are generally more averse to actually using them and more concerned with supply chain attacks than in the NPM world.

(Source: Among other things, I've been hanging out in /r/rust/ since around 2013 and observing the reactions to announcements of that sort of crate.)

That said, one reason you would see more smaller crates is that, in Rust, the crate is the primary unit of parallel compilation, not the file, so, within reason, smaller, more numerous crates allow compilation to be parallelized more effectively.


Re: Why not do this

The Linux kernel is in GNU's extended C dialect, and it builds its own fanciness on top of that, so it's not the C99 that the c2rust tool knows how to ingest.

(Yes, such a tool exists. Its purpose is to produce `unsafe`-heavy Rust code that continues to pass all the same test suites, so you can take what it spits out and focus on the refactoring that can't be reliably done mechanically.)


Re: Memory safety

More specifically, those "few extras" that `std` adds over `alloc` are APIs that depend on having userland things like a filesystem (`std::fs` stuff like Rust's analogue to opendir(3)/readdir(3)), a network stack (`std::net` stuff like Rust's analogues to connect(2)/listen(2)), etc.

Thus, for a microcontroller that can support a heap allocator but has no OS, you can implement a backend for `alloc` without pulling in those things, but being able to do so doesn't mandate that it be done for bare-metal platforms with no heap.

Rust is eating into our systems, and it's a good thing


Re: Systems Programming Language vs. Application Programming Language

Because they intuitively recognize that, in addition to being capable of low-level programming, Rust also has a lot of high-level constructs and, more importantly, it cares a lot about being an imperative systems programming language in the original definition of the term, where languages with comparable guarantees tend to be functional languages like Haskell.

To reference a quote used to good effect in https://willcrichton.net/notes/systems-programming/ :

> In Systems Programming Languages (Bergeron et al. 1972), the authors say:


>> A system program is an integrated set of subprograms, together forming a whole greater than the sum of its parts, and exceeding some threshold of size and/or complexity. Typical examples are systems for multiprogramming, translating, simulating, managing information, and time sharing. […] The following is a partial set of properties, some of which are found in non-systems, not all of which need be present in a given system.


>> The problem to be solved is of a broad nature consisting of many, and usually quite varied, sub-problems.

>> The system program is likely to be used to support other software and applications programs, but may also be a complete applications package itself.

>> It is designed for continued “production” use rather than a one-shot solution to a single applications problem.

>> It is likely to be continuously evolving in the number and types of features it supports.

>> A system program requires a certain discipline or structure, both within and between modules (i.e. , “communication”) , and is usually designed and implemented by more than one person.

In other words, by the original definition that Rust pays a lot of attention to, Java and Go are also systems programming languages, because systems programming is about producing complex infrastructural components with a long service life that need to be maintained by shifting teams... like the networks of microservices Go excels at.


Re: Recovering C++ Programmer

Rust has a "release a minimum viable product now, enhance it later" philosophy.

They don't have a stable ABI now, but that doesn't mean they've rejected the idea forever.

Among other reasons they don't have a stable ABI yet, they're still finding ways to improve it. For example, Rust v1.0 didn't ship with automatic structure packing, but Rust now has it if you don't use #[repr(C)]` to request a C ABI layout.

Also, in the mean time, there exist crates like abi_stable (https://lib.rs/crates/abi_stable) which allow the problem to be worked around. (abi_stable does Rust-to-Rust FFI through the C ABI, handling the task of making sure, at compile time, that both sides share the same interpretation of the higher-level constructed being pinned into stable forms by the C ABI in the middle.)

They also care enough that one of the big names in their low-level work made the frustrating discovery that there is no one "the C ABI" even within a single platform when writing a checker to make sure Rust could reliably speak "the C ABI" without having to carry along a C compiler.


(eg. GCC and LLVM don't agree on how to represent __int128 because the AMD64 SysV ABI document is merely human-readable, not an executable conformance suite.)

> I wrote this dang thing to check for mistakes in rustc, I didn’t expect to find inconsistencies between the two major C compilers on one of the most important and well-trodden ABIs!


Re: Rust versus Linux distros

Tier 1 is quite literally "we have access to CI farms using this hardware-software combination that every push and PR gets natively built and regression tested on".

Tier 2 is more of a "We also do these on our CI, but we can only cross-compile for them".

They're pretty conservative about what they're willing to promise because they've made "fearless upgrades" one of their slogan goals.

(I believe, if Microsoft weren't donating Azure capacity for their CI, their development process would be seriously bottlenecking on CI capacity.)


Re: Pronunciation?

As a fellow canuck, I rowt packets and plan my root on the roads.


Re: Yeah They're Wrong

The Pascal-ish "let <name>[: <type>] = ..." syntax is to avoid needing The Lexer Hack and comes from Rust's Ocaml ancestry.

(Any time you wonder about a piece of Rust syntax that's different from C++, it probably boils down to "Rust is kinda an ML-family language in a C++ trench coat".)

Same reason typecasting is `*x as Y` rather than `(Y) *x`.


Re: A Bit More Complicated

Optimizers frown on that, even in C, and there are experiments ongoing with architectures like CHERI which encode pointer provenance in a hidden second 64 bits of the pointer so, if you step outside of the allocation your pointer descended from, you get a hardware trap.


Re: Something C++ can do that Rust can't

...and, cbindgen's support for C++ constructs aside, there also exist crates like flapigen (https://lib.rs/crates/flapigen) which can do a lot of that for you to ensure that it's a compile-time error if the Rust→C→C++ parts don't line up.


Re: Something C++ can do that Rust can't

There's also Federico Mena Quintero's blog, where he detailed the process of incrementally rewriting librsvg from C to Rust.



Re: Something C++ can do that Rust can't

Rust has `std::ffi::CString` (allocate/free in Rust) and `std::ffi::CStr` (can be wrapped around memory allocated outside Rust) types for null-terminated strings, so you only need `unsafe` for the `from_raw`/`from_ptr` constructors which rely on you to ensure their input is in compliance with the expected invariants. (Stuff like "must be a non-null pointer to a null-terminated string".)

The rest is on you designing an API that ensures they can't be used incorrectly.