Hacker News new | past | comments | ask | show | jobs | submit login
C-rusted: The advantages of Rust, in C, without the disadvantages (arxiv.org)
171 points by signa11 on Feb 20, 2023 | hide | past | favorite | 142 comments



"The analysis is rigorously intraprocedural, i.e., it is done one function at a time, using only the information available for that function in the translation unit defining it, which includes the annotations possibly provided in function declarations."

So, in the examples, when something calls "read", what does the analyzer know about "read", and how much of its "char *" buffer it overwrites?

If you're going to do formal static analysis, the big wins come from automatically detecting that thing A is inconsistent with thing B way over on the other side of the project. That's the stuff humans miss. If you have to annotate everything to death, nobody will use your tool.

This is sort of an ad for the "ECLAR software verification platform", which is apparently some expensive tool. The site is all onboarding, no info, "ask for quote" B2B.

From the paper, you can't tell much about what they're doing. From the ECLAIR site, you can't tell much about what they're doing. So, no clue if this is a good idea or not.

[1] https://www.bugseng.com/eclair


> “using only the information available for that function in the translation unit defining it, which includes the annotations possibly provided in function declarations.”

> So, in the examples, when something calls "read", what does the analyzer know about "read", and how much of its "char " buffer it overwrites?

As the text says: “the annotations possibly provided in function declarations.”*

The PDF also says “the large part of the result is obtained without any annotation at all, thanks to the fact that the C Standard Library and the POSIX Library have been annotated once and for all (and the same can be done with any commonly used library).”


But you can automatically derive a lot of information, e.g. after

  if (!x) return;
you know that x is non-zero etc. Or after

  x = malloc()
you can know that x is - at this point - a pointer that has exclusive ownership (if x is non-null).

So I think it is a viable approach. I have a toy C front end that does something similar. While this project stalled due to lack of time, I think it is doable with a modest amount of annotations and not more pain than Rust.


Sound (key word here) analysis of this form, which is known flow-sensitive, is remarkably slow. Soundness is required if you want "provable" rather than "99.99%" correct.

So much so that we have even had scalable context-sensitive interprocedural analysis for at least a decade longer than we have ever scalable flow-sensitive analysis in most contexts.

For example, pointer analysis, which matters here, is ni that class.

It is easy to find context sensitive flow-insensitive pointer analysis that scales very well, and has been easy for >1 decade.

flow-sensitive -- still much harder in practice. A few papers here and there, but ...

You can do halfway flow sensitive analysis with SSA and get it in a reasonable time bound but it's not the same for something like this.

This is more of a problem than something like the standard library handling, because the standard library is a library and can be pre-computed into summaries, and the relevant summaries change very infrequently

(IE to the original example, how much of the buffer read overwrites does not change every glibc release)

Theses sorts of annotation based schemes are also not new - we've also had summary based algorithms that can do this sort of thing for decades.

The algorithmic capabilities here have not really changed, and the improvement in computing power has not helped enough because lots of the sound algorithms are, worst case, cubic or exponential.

In the end just remember if it was cheap, easy, and usable, it wouldn't be a problem, because it would already be done.


I don't know if sound analysis (as in no false negatives or also precise as in no false positives) is just slow or if it depends on the language constructs and the amount of flow sensitive mutable state that is being tracked.

Do you have any references on why that would be slow? That's of interest to me :)

Also, perhaps is there a distinction to be made between data flow and control flow sensitivity?

Seems like these kinds of analyses are increasingly added to languages for nullability tracking so it might not necessarily be that slow. Especially if the type system is of help so that the analysis can be incremental, per compilation unit.


My personal experience has shown me that static analysis of this kind does not scale for C, the complexity of showing just the memory safety of even simple programs grows astonishingly fast.

Proof overhead for memory safety can frequently be on the order of 5-10 lines of annotation per line of code.


This is exactly why the Rust folks chose the kind of analysis that they did for the borrow checker. It's quite co-extensive with the subset of memory-safety proofs that happen to scale up easily and compositionally to larger programs.

That said, it would still be very helpful to have true first-class support for the GhostCell pattern in Rust, so as to be able to prove safety for somewhat more complex designs (including safe doubly-linked lists) albeit contained within a single module.


Yeah, ask yourself, if you see

    if (!x) 
      return;

    // statment here

    do_something(x);
Which statements on the line saying "statement here" would invalidate the zero check for x?


Now add threading, hardware traps and signals into the mix.


That greatly depends on how many memory-safe programs you want to prove are memory safe. If it's the same subset of programs that a language like Rust can prove to be memory-safe, the annotation overload need not be higher. If you want to prove that an arbitrary memory-safe C program is memory-safe, then, indeed, you'll likely need many more annotations. Even in those situations, adding more annotations or restructuring the code may be cheaper than a rewrite in another language. Sound static analysis for C is already not uncommon in some important domains.


Thanks. This is exactly my point. Instead of Rust, we could use a subset of C with suitable annotations and will not require any more annotations than Rust.


> If you have to annotate everything to death,

Isn't this how rust works?

People seem okay with annotating everything.


No, because of language semantics much of that is already in no need for the annotations, other than one needs to go away from the well behaved path.


True, but C programs that follow the same structure would require about the same amount of annotation. A language can force you to write programs in a way that makes some properties easy to prove, but if you write them in that way, they can be easy to prove in any language. The difference is that instead of rejecting a different kind of program, the analysis will fail to prove, at which point you can either add more annotation or restructure the code to make it easier to prove.


They need much more due to C´s semantics, that is why there are companies like the one on this thread selling verification services and tooling.

It is also the reason why Microsoft has acknowledged their idea of lifetimes checker did not went as well as planned, and they had to rethink it,

https://devblogs.microsoft.com/cppblog/high-confidence-lifet...


For arbitrary code, which is precisely my point. Code written in C in the same style as Rust is no harder to analyse than Rust code. What a new language can do is reject code that's not easy to analyse. It's code that's not written in that way in C that's hard and requires either more annotations or a restructuring (which may still be easier than a rewrite in another language).


It's a good thing all developers in all groups on all projects at a company always conform to the same style in the real world. Otherwise the plan for annotating C might run into some stumbling blocks.


And it's also good that migrating a codebase to a new language with questionable prospects carries no risk or cost. Otherwise its adoption rate could disappoint.


I am not okay with it, which is why I never bothered to learn Rust.

In my (caveat-filled) analysis of verbosity, Rust is on the wordier side of languages (about as verbose as Java).

https://danuker.go.ro/programming-languages.html#non-math-ma...


Did you learn C? According to the chart you linked, C, C++, and Go are all more verbose than either Java or Rust.


I did, being forced to in high school. I was never fond of it.

Go is only a bit more verbose. Programs have a wide variability which is not graphed.


So perhaps it isn't the verbosity per se of Rust that irks you so. That's fine. No one needs to learn or not learn any given tool.


Being able to learn C doesn't mean C's wordiness didn't irk me. It did.

In addition to verbosity, C bothered me with mandatory types, undefined behavior and having to manage memory myself.

Rust is not much better. It still has types and memory management. A lot[1].

I don't want to deal with that. The computer should figure it out. Not having to specify all that also translates generally to shorter programs, and this is why I appreciate terseness.

[1] - https://www.brandons.me/blog/favorite-rust-function


Hm but isn't that how all static analysis tools, including Rust'a compiler itself, work?

I.e.: You know the function body is, according to some definition, let's say aliasing, consistent. You annotate the function signature, thereby expressing formal contracts for that function any caller has to fulfill; given the contracts are fulfilled, the function call will then be consistent.

Meaning, you prove the function body is consistent, you annotate the function, and you then get the guarantee that the function is correct for any callsite that fulfills the contracts. If you want to prove this using a formal prover, you have to annotate the function, and annotate the callsite in such a way that the prover can prove that the contracts are kept, AT THE CALLSITE.

Or am I missing your point?


Isn't the difference in it being required, and opt-out (unsafe) in rust, but opt-in here? Also, my understanding is the rust compiler guarantees "soundness" in safe rust, so it checks and validates that the function signatures (with annotations like lifetimes) are correct


Also Rust's macros are logically part of Rust whereas the C preprocessor knows nothing about the C language.

To say the C preprocessor complicates analysis is an understatement.


Ah, thank you for pointing this out, it all makes a lot more sense to me now. The table in the paper alone was a giant red flag for me.


I don't remember the original source, but there's some classic frustration with these kinds of tables in academic papers. It's a "look at us, we're good at everything!" selective cherry-picking that omits honest discussion about the limitations of the approach.

Although honestly, the red flag for me was the mention of a "field-sensitive" analysis in C. My experience doing static analysis on C code is that it tends to be so reliant on type punning that field sensitivity ends up kind of not working, at least not without significant effort on detecting and handling type punning in some manner (to say nothing of all of the fun ways people figure out how to encipher pointers).


I think showing with static analysis that existing C code is safe is very hard.

But if you start with modern and cleanly written C and avoid certain techniques (such as type punning) I think it is clear that this can work. Rust fundamentally does nothing else.


> But if you start with modern and cleanly written C

I think I see a flaw in this plan. Everyone is on the curve, but not everyone will be as far along the curve as you or I would like.

The advantage of Rust is that the compiler always enforced all the good practices unless you explicitly opt out, and frankly the error messages that come out of the Rust compiler are a lot more helpful than the ones from the C compiler.

It's hard enough getting folks to treat compiler warnings as errors. Expecting every professional (let alone hobbyist) developer to conform to best practices overall may be expecting too much, and when it comes to security and reliability, we really are all in this together and need to make the best of what we've got.


People who do not want to write safe code will also not use Rust. (Or then use unsafe Rust a lot).

If you want your programmers to write safe code and are in a position to force this, it makes no difference whether you mandate the use of Rust or whether you mandate the use of a safe C subset enforced by a compiler flag.


There is an inherent difference between a language where safety is opt-out (safe by default) and opt-in (unsafe by default).

Ignorance or forgetfulness leads to safety by default in Rust. A single failure of vigilance in C leads to the status quo of unsafety.

This is no small difference. If someone doesn't want all the guardrails of Rust, there are still options like Nim and Zig that provide better options than C for greenfield systems projects today.


when the paper started the classic "I have no clue what typedef's actually are in C and what their interpretation is" I was like hmmm... glad this explains why it is just a terrible, biased article


RE the point about catching mistakes involving far apart pieces of code, they are clear that it's "interprocedural", so the analysis is only within a single function at a time. Like with rust, there is a focus on annotating function inputs and outputs, with a lot of inference within functions. I am curious if there's a way to quantify how quickly the safety propagates as you do gradual typing. If you annotate 20% of the functions in a typical codebase, does 90% of the runtime data pass through an annotated function boundary at some point, catching 95% of the ownership bugs?


It's intraprocedural.


Indeed. Embarrassing! I consciously avoid using "intra" or "inter" in English for this reason, and when I do because of someone else's jargon I also say what I mean to disambiguate. Unfortunately we can't deprecate english to avoid these mistakes... but maybe we can design a system of macros we can insert into our posts to statically check if our usage is correct.


I always think of "international" as the baseline, because I know it means among multiple nations.

Intra- is "the other one".

Also, isn't "inter-" vs "intra-" a Latin idiom? It's present in all Romance languages. English got it through French.

Luckily I think this is an area where tools like ChatGPT (and modern word processor tech) can help us all out.


You can do this. But it isn't C anymore, it's just a DSL on top of C and because it is a thing that is layered on top of an existing language that language is still there and you will have to make sure that someone doesn't simply use the original unsafe language constructs.

I've built a thing like this for a project that had zero tolerance for any of C's well deserved faults, and yet, had to be written in C. I borrowed heavily from various other solutions (notably: Erlang) to ensure that the project was as safe as I could possibly make it. But I was always acutely aware that it only took one team member to declare a void * to an unbounded array for things to break out of that carefully constructed illusion of a safe jail.

Most of the work was done using some pretty tricky (and nifty!) macros and I really liked the end result, but I would have very much wished for that end result to be based on something more solid than C as the foundation. If you go down this route in the present day, unless you absolutely have to use something else. You'll be far happier and you will not have to be eternally vigilant against someone taking a shortcut.


Sometimes you can work around a "has to be written in C" requirement by generating (known-safe) C at build time and avoiding writing it directly.


It is as much C, as MISRA, Frama-C et al are.

Or C coding on Windows with SAL.


Indeed. But I see these as workarounds for very particular requirements, not as ways to build new software in a responsible way if other options exist.


It's certainly better with such safety annotations than without...


It’s not clear to me that it necessarily is, if those annotations provide a false feeling of security. C-rusted doesn’t seem to have a real story for preserving invariants in linked-in but not locally compiled code, which is the main thing that makes C a valuable ecosystem.


To be fair, Rust does not really have such a story either. Externally compiled code (i.e. code not built with the exact same version of the compiler) must interact via the unsafe C ABI and be re-wrapped locally into safe Rust-friendly constructs. There are crates to make this a bit easier, though.

Things might be different if you could preserve useful invariants all the way down to binary code, of course. Then externally compiled code could also be meaningfully checked for safety.


The difference is culture and tooling: linking against random .so files is normal in the C world, while Rust strongly encourages you to use source dependencies.


For the time being, as Apple showed by their gigantic effort with Swift ABI, there are C and C++ shops (and Objective-C ones) that really care about dynamic libraries, which any alternative needs to take into account for their adoption.

The main issue is the culture, being more in line with ALGOL/PL/Ada/Wirth languages point of view of why security matters, even if there is a bit of unsafe core around.


[flagged]


It's got to be possible to have a conversation about other languages without these - frankly boring - comments in them. Maybe consider that Rust the language does not benefit from this kind of evangelism if you have no clue about the backstory of that particular project?


I agree, these ignorant Rust fanboy comments don't help Rust gain any goodwill, and even convey the idea that their vocal proponents are clueless and completely out of touch with basic industry requirements. It's unthinkable for any project to just casually drop everything and go for a complete rewrite in entirely different programming languages and tech stack. But this blend of Rust fanboys keep on insisting this is a reasonable thing (only when it's Rust, oddly) and have the gall of trying to turn things upside down and make believe that it's unreasonable to not jump head first onto a major rewrite.


I've spent quite a bit of time amongst the Rust community, and I have never actually seen any of these RiiR evangelists that are complained about so much on HN.

I'm not saying they don't exist, but they are a much smaller portion of the community than HN would have you believe.


> I've spent quite a bit of time amongst the Rust community, and I have never actually seen any of these RiiR evangelists that are complained about so much on HN.

You're telling me you don't see "why not rewrite it in Rust" posts in a forum dominated by people who are enthusiastically working on Rust codebases?

In the meantime, you did noticed that RiiR is already a meme, didn't you?


They are like the Bernie Bros of programming languages.


This is why I always make remarks regarding how Rust still doesn't have a proper solution for many ecosystems where C and C++ are the only available tools (with an ecosystem, not only the compiler), which will be around for decades and need to be catered for somehow, and if one can live with automatic memory management, there are plenty of safe languages to chose from.

When one comes with this advocacy that safety === Rust in every discussion thread, this automatically shuts off the recipient of the message, which could otherwise be willing to actually listen to it.


Exactly this. It shows a very limited exposure to the realities of the IT world and the vast amount of legacy code and systems that is out there that really are not going to be rewritten in Rust or any other language any time soon and likely not ever. Rust isn't a silver bullet, and besides the value of a battle hardened codebase is substantially greater than the value of a freshly rewritten codebase in any other language.

'Rewrite it in Rust' is a mantra that makes a whole slew of assumptions that need to be validated before it can be considered a realistic option.


This sounds like JavaScript: The Good Parts revisited. Agree with everything you’ve written. However, in the rare situation that one has to go down this path, a linter/static code analyzer can prove to be a life saver. Found some on this page: https://github.com/caramelomartins/awesome-linters#cc


Luckily, no one ever used The Bad Parts again after that book was published.

Even getting folks to reliably use a linter can be a chore. Getting all C coders current and future to use these new techniques seems wildly optimistic to me.


Is there maybe a linter you can use with C and then use as a required status check on merge requests in GitHub / Gitlab?


Yep, the company behind this advertises online demos in gitlab


but can't you lint for such things or even just grep? The world will always build a better idiot, we're just trying to reduce the attack surface.


>But I was always acutely aware that it only took one team member to declare a void * to an unbounded array for things to break out of that carefully constructed illusion of a safe jail.

This is why code reviews are a thing. If you have competent programmers, with a CR process as part of CI/CD pipeline, you really don't need language features to handhold programming.


Even with the best code reviews, even with the best development practices, even with the most comprehensive automated testing processes, you still do need a language to help you.

Case in point, even SQLite still has CVEs relating to memory safety: https://www.sqlite.org/cves.html


I dunno, those bugs look mostly no- or low-impact. Saying somebody needs a language for that is a bit strong in my opinion.


The page itself literally leads with multiple extensive statements about how the sqlite CVEs are exaggerated and inaccurate:

> Grey-hat hackers are rewarded based on the number and severity of CVEs that they write. This results in a proliferation of CVEs that have minor impact, or no impact at all, but which make exaggerated impact claims.

Also how most CVEs require arbitrary SQL injection (and if you have this access, you're screwed already):

> Almost all CVEs written against SQLite require the ability to inject and run arbitrary SQL.

It also explains that:

> Few real-world applications meet either of these preconditions, and hence few real-world applications are vulnerable, even if they use older and unpatched versions of SQLite.

---

It also explains that many CVEs are denial-of-service due to division-by-zero, which in Rust can only be caught by using the opt-in `checked_div` so would be equally safe in C and Rust(?)


It is true that a lot of people like to file CVEs for extremely theoretical security issues.

See for example - https://nvd.nist.gov/vuln/detail/CVE-2023-0687

The CVE is correct that the “gmon” component of the GNU C Library contains memory corruption bugs. In fact, I’ve found even more than the specific one that CVE is about.

But, the claim that this is a security vulnerability is a bit silly. These are profiler functions, which are usually only called in non-production builds with profiling enabled (gcc -pg), and even then only from CRT startup code. It is rather unlikely an attacker can exploit any of these bugs in them without already having the ability to run arbitrary code in the process, at which point they don’t need these functions, they’ve already got all these bugs have to give them.


Yeah, this kind of thing is tricky. Rust has had some CVEs filed against the standard library that are CVEs because of Rust's guarantees. Same issues existed in the C++ standard library but since it's UB, not a CVE there.


Do the C++ libraries require changes as a result of these issues?


Nope, their docs just say "don't do that" and so you're expected not to do that.


Ok, so this isn't an issue, right?


I'm not sure what you mean by "isn't an issue."

All I'm saying is that the CVE process is a human one, with lots of nuance. You're pointing out one aspect of that, that some CVEs are very practical, and others are more theoretical. I was trying to chime in with a similar way in which this is expressed, in that an identical bug in the standard library of one language may be a CVE, while in the other, it may not be a CVE, even with the same problem in both of them. That's "not an issue" in the sense that yeah, of course, Rust cares about this a lot more, so it's a more serious problem in Rust, so this process is legitimate, but it is in the sense that depending on how you're trying to do comparisons, there's more complexity than simply tallying up CVE counts.


CVEs aren’t really anything but an identifier for a problem. It says nothing about its severity, exploitability, or in some cases, whether it is even an actual bug. You can effectively get one for ~free. This is one of the reasons why tallying up their counts is not useful, but others include things like “people focus on some software more”.

With that said, I wouldn’t bring up this distinction here. The problem here is identical but Rust bills itself as a language where it takes responsibility for correctness bugs while C++ is a language where correctness is something that the programmer is supposed to provide. That doesn’t mean the Rust CVE is any less valid or complicated than the other CVE, it’s just that the bug would get assigned to Chromium or IOAccelerator. So if you’re saying that you shouldn’t just look at the number of CVEs and claim that Rust is somehow less secure: yes, absolutely. But if you’re saying this because you want to point out that Rust CVEs are somehow lesser because they are self-imposed, then no, that’s not true.


> if you’re saying that you shouldn’t just look at the number of CVEs and claim that Rust is somehow less secure

Even more general than that, it’s not about Rust specifically, just that number of CVEs alone, with no other context, is a bad metric.

> That Rust CVEs are somehow lesser because they are self-imposed

I am not saying that, yes. That would be incorrect.


Code reviews are great, competent programmers are also great. Even the best programmers make mistakes.

Additionally, the easier memory safety is, the more time those competent programmers can devote to work on new ideas instead of babysitting code.


I don't think I can agree with this. Competent programmers are no silver bullet against whole classes of possible errors. Mistakes can be made, mistakes can be missed during code review. The vulnerability repositories are full of those.


Code reviews don't replace automatic tests or even linters. What leads you to believe they replace memory management errors?


You call it handholding. I call it partial automation of code review. Why waste expensive hours of my co-workers' time when I can have a program do it in seconds for a few pennies of electricity?


Rust code tends to rely extensively on generic containers to encapsulate various safety properties. That will be hard to replicate in C.

Still, I’d like to see how it works out in practice. But where’s the code? Judging by the website for ECLAIR, which is the basis of C-rusted according to the paper, it may not be open source:

https://www.bugseng.com/eclair

In that case, it may still be useful in the tradition-heavy world of safety-critical embedded applications (which the paper alludes to in mentioning MISRA and certified toolchains), where each codebase is a proprietary island. But it won’t be usable for general-purpose C programs or libraries, nor will it be possible for the community to evaluate on its merits.


In my opinion, it's terribly disingenuous for them to argue in favor of this approach and use TypeScript as an example without acknowledging that a great deal of making TypeScript practically useful involved investment into adoption and support, and the open nature of it. C-rusted will never expand beyond a niche of some industries if not opened in some form, and likely, if it's actually a good idea another tool will eventually eclipse it.

That's a shame, as it seems like a pretty decent idea, even if I feel like the paper is written a bit like an advertisement (it feels a fair bit biased: it's hard to argue that you can't adopt Rust incrementally at all even if it doesn't allow for gradual adoption in the same manner as C-rusted or TypeScript. Also, it definitely doesn't demonstrate a similar competency towards being able to express things safely as Rust does.)


Without the disadvantages? What advantage does C hold over Rust if you value a composable language which is safe and expressive?

With composable I mean the ease in which you can include a external library without having to study it first. Whenever I had to use C this was always a bottleneck and you resort to copy paste hell, with slight changes to the original source.


> Without the disadvantages? What advantage does C hold over Rust if you value a composable language which is safe and expressive?

Having existing C codebases in production which are time-tested and stable and reliable is a huge advantage of having to rewrite them from scratch, don't you think?

Also, you can check out C code from 20 years ago and build it in your personal laptop with ease, and be able to do the exact same thing 20 years from now. Meanwhile, Rust still fails to put together a single specification, let alone a standard one, and relies on reference implementations that may or may not exist in a few years.


Safety critical software has laws it needs to follow. Testing and validation can be so expensive it doesn't make sense to touch old code.

I'm an advocate of Rust for most software, mind you. The safety you get from enforcing ownership at function and crate boundaries is allowing the package ecosystem to grow rapidly at a high quality. The safety win partially mitigates the safety loss you get from adopting hundreds of small transitive dependencies maintained by random people on the internet. But if you've spend tens of thousands of dollars having engineers test and validate some piece of safety critical code, you're going to need a really good business case for touching it at all.


> The safety win partially mitigates the safety loss you get from adopting hundreds of small transitive dependencies maintained by random people on the internet.

That advantage may be temporary.


Isn't this confusing memory safety with safety?


Confusion? No it's just flat out obfuscation.


> What advantage does C hold over Rust if you value a composable language which is safe and expressive?

Language stability, tons of tooling, validation, decades of experience, plus the fact that you might have spent 500 million dollars to develop your existing codebase.

Not to mention Rust is still a moving target and it's not ratified for safety-critical uses.


I like C more than Rust because for my taste, Rust is too complex. I also like that C has fast built times which is important to me. C is also far more portable and has a huge ecosystem. Another big win is that you can gradually transition older code base, while I feel the "rewrite in Rust" approach throws out the baby with the bathwater. Generally, "rewrite everyhing" is often infeasible and even if it is, it is usually misguided. Another thing is that to justify rewrites, one has to over exaggerate the benefits of Rust via the problems of modern C (I don't doubt there is a lot of rotten old C code around), which poisons the discussion.


The biggest reason is so I can use all the existing embedded driver and library code without re-doing it. That comes with it’s own safety challenges of course.


Not a new idea. There's plenty of prior art:

- Cyclone: https://www.cs.cornell.edu/projects/cyclone/ (2002)

- SAL: https://learn.microsoft.com/en-us/cpp/code-quality/understan...

Not to mention languages that are generally safer such as Ada.

They also fail to present a code example that looks more ergonomic than Rust.


Having worked at Microsoft where SAL is used extensively, I can tell you it's entirely inadequate for actually preventing memory safety issues. At best it can give you things in the category of better warnings. At worst, you can annotate incorrectly or not at all, so it doesn't even work with correct info.


Which kind of proves the point of all these approaches not being able to be nothing more than bandaids.


I'm not sure it does prove it. It could just be a story of poor execution.


But that was not the way it was sold to developers and stakeholders.


Also from MS: Checked C[1], which aims to detect many of the same bug classes.

I agree entirely about the ergonomics, and I think the authors also oversell what “safe” means for C-rusted-checked code, versus what safe means in Rust. There are some nice ideas here (and I’d like to see the implementation!), but it’s a stretch to say that something as incremental as this can provide the same program-wide guarantees that safe languages can.

[1]: https://www.microsoft.com/en-us/research/project/checked-c/


Cyclone is not strictly backwards compatible with C.


This seems more like the disadvantages rust, with the disadvantages of C. What I really want is the footguns of C with the ergonomic modern veneer of Rust's nicer syntax, built-in types, control structures etc.


Maybe Zig[1]?

[1]: https://ziglang.org/


I'm still waiting on a Zig book.


> What I really want is the footguns of C with the ergonomic modern veneer of Rust's nicer syntax, built-in types, control structures etc

Would unsafe Rust work for that, or is there a C footgun you need that that doesn't provide?


Using unsafe rust to try and write "rust without safety" doesn't work particularly well IMHO. Arguably that's a feature, unsafe rust is meant for implementing things that you couldn't implement in safe rust, not meant for just wholesale avoiding the borrow checker and going on with your life.

The biggest thing that is missing is a `->` operator (or the safe-rust solution of auto dereferencing with `.`, which is disabled for raw ptrs). Having to write (*foo).bar all over the place is not a good experience.

The second biggest thing that is missing is a footgun. Auto casting integer types all over the place. To different integer types. To offsets for pointers. Etc.

Disclaimer: It's been a few years since I really dug into the unsafe side of the language, maybe things have "improved"?


I really want -> in Rust too (or perhaps .*). I don't see why such a thing would be controversial.


I'm interested in seeing something like that as well. The controversy is entirely "should we spend syntax space on that" and "if so, which part of the syntax space".

There are some proposals going around that would solve that problem.


Cool, but the paper's criticism of rust as a moving target also applies to the various pre-processor annotations in C-rusted. While true that the C preprocessor is used to make the annotations vanish (thus yielding normal C code), it is disingenuous to claim that the standardization of ISO C means that C-rusted is a stable target for any programming project. If you take that at its word what you get is that the unsafe language is standardized, but the safety features are not, which means that it is very easy to leak incorrect code to the C compiler, and then customers.


Rust is much less of a moving target the longer it’s around. It’s been pretty stable for some time with only improvements at the edges that don’t break backward compatibility. Most of these seem to be filling in gaps in the type system’s capabilities or rounding out the standard library.

Has there been a breaking change in the past few years?


"pretty stable for some time" is not the endorsement you think it is. Some companies don't even use C++17 and stick to C++14.

At the same time, Rust has grown to a large and complex thing and deserves a large update to make it more dev friendly (what C++ did years ago). I expect at least one big update before it can settle.


It has that, it's called editions which have in fact made our lives easier. You don't seem to understand that editions don't break backward compatibility. Those companies would be welcome to keep using Rust 2019, but they won't have to because Rust tooling is not a nightmare, unlike C++.


> Rust tooling is not a nightmare, unlike C++.

Please try this:

1. Install rustup on a clean Ubuntu 22.04 x64

2. Open the rust embedded book, go to the getting started chapter

3. Try the first part

Early in the tutorial "cargo install cargo-geneate" will gail due to E0282 in git-glob...


The editions mechanism is incredibly weak, every time I ask "Can this be fixed with an edition?" The answer is no.


Editions can only represent basic changes and the standard library isn't part of them.


Some companies stick to ANSI-C and use a compiler binary from the 90s because new things are scary™. So what exactly does that tell us?


That people claiming Rust is stable don't really understand the industry?


It's true that somehow C++ programmers rationalise completely new programming languages with incompatible syntax every three years as "stable" and Rust's stability as "unstable" but turns out that the people actually developing it don't agree with you that just changing everything would somehow make it "settle".


That stability comes in a dead trees tome that everyone should certify their compilers against.


> That stability comes in a dead trees tome

No such "dead trees tome" exists. ISO will explicitly point out that what you're spending an eye-watering sum of money on is just a PDF.

Some of the National Bodies will tell you that you can buy this document on paper, but what they're actually doing is contracting out to a local Print On Demand service which either didn't tell them it has a document size limit or they didn't listen.

If you splash out anyway eventually what you'll get in the post, instead of your imaginary tome is a CD with the PDF on it.

> that everyone should certify their compilers against.

Try for a moment to imagine that all the GCC and Clang volunteers own legal copies of the actual ISO document. Now, stop laughing and read. Nobody cares about the actual document, in 1998 there really were academic libraries who bought C++ 98, and they might still have C++ 98, but that's a 25 year old document. Today those libraries would tell an interested user, "I'm pretty sure this is online, go away and search" and they'd be correct.

Because it's a PDF not a paper document, ISO C++ is a moving target, what's stable about that?

One of the few things about C++ that I unambiguously admire is std::format() introduced in C++ 20 -- but actually the most important feature of std::format() wasn't in the published C++ 20 ISO document, it's an erratum, pasted in much later because it's obviously needed.


Plenty of industries care, that is why Ferroceone wants to make it possible for such industries to also care for Rust.

ISO C++ is only a moving target if one ignores that there is an industry that certifies compilers for specific standard versions.

I imagine a few people at Red-Hat, or the dozens of compiler vendors that take advantage of upstream work in clang can afford a couple of copies of the standard.

After all, they have circa 40 years of experience doing so since ISO/ANSI C89 was released.


> ISO C++ is only a moving target if one ignores that there is an industry that certifies compilers for specific standard versions.

That's what is so funny. You can indeed get the rubber stamp, and it's worthless. Have you watched that scene in "The Big Short" where FrontPoint goes to the ratings agency and basically gets told the agency knows these products are bullshit, but they don't make money unless they say it's good so that's what they do ? Turns out a "ratings agency" wasn't legally promising anything at all, they existed solely because people felt like if someone else says it's good, even if they were paid to say so, well it must be good. Hilarious.

But that doesn't matter because nobody wants a C++ 20 compiler which does what the ISO Document published in 2020 says anyway, because that's bad you want a compiler which does what the current document now says about C++ 20. It's a moving target.

And I doubt very much that the "dozens of vendors" have even stayed awake long enough to read much of the readily available and up-to-date "draft" document, much less that they insisted their employer spend actual money on the useless and perpetually out of date official ISO document. It's not a great piece of technical writing.


See, this is the kind of atittude that puts off many C++ devs out of hearing about Rust.

A reply quite fitting of the whole RIIR folks.


Nah, this is not a universal truth.


Nothing is universal, and everything is relative.


That's quite a universal statement.


This seems quite similar to Windows SAL attributes, it is better than nothing, but doesn't really get us there.

https://learn.microsoft.com/en-us/cpp/code-quality/understan...


Typescript can type-check javascript files that are annotated with JSDoc comments. With those, you can express almost the entire type system of TS while keeping your files directly interpretable by the browser without preprocessing. Are there any experiments like that for C?


This sounds like the equivalent of Typescript for C.


correct. They say so in the paper.


> So, what does the current ferment about Rust tell us? That the industry is ready to accept that programmers take a more disciplined approach by embracing strong data typing enhanced with program annotations.

I have a question. Who asked for this? Like who exactly raised their hand and said yes, I want a systems programming language that won't let me compile syntactically and semantically correct programs because they don't follow an arbitrary ownership model?


I suspect that you’re not asking in earnest because otherwise you’d look up the Rust Foundation’s membership page[1] and see for yourself which companies asked for this emphatically enough to put money behind it.

We use languages that impose other “arbitrary” constraints on us in order to save ourselves from our mistakes. For example, we avoid implicit conversions from strings to integers, or we use type systems that make sure that we don’t treat “dollar” type decimals as if they were “euro” types. The ownership model is a similar concept but to avoid memory bugs.

[1] https://foundation.rust-lang.org/members/


Right, I understand that big corporations are pushing a new systems programming language that they say saves programmers from their own mistakes. My question was whether any programmers actually asked for it, and if so, which ones?

> We use languages that impose other “arbitrary” constraints on us

> The ownership model is a similar concept [to type checking]

Except we didn't. K&R rejected Pascal for their work on Unix precisely because it was too strongly typed and didn't provide sufficient escape hatches. Arrays were typed by length, there was no pointer arithmetic, there was little or no typecasting or coercion, no generic pointer types, no null pointers, etc.

All these restrictions that were in place to create a safer language made Pascal completely unsuited to writing allocators, buffered IO, and other OS internals. So instead, they ditched Pascal and created C and had Unix up in running in just a couple of years. Maybe there's a lesson there.


> My question was whether any programmers actually asked for it, and if so, which ones?

I have to admit, this question sounds very strange to me.

Corporations don't get work done. People do. Rust has been designed and implemented by programmers.[1] There's countless hours of talks and interviews and many articles and books written on Rust by programmers. They did all that work without being forced by anyone.

> All these restrictions that were in place to create a safer language made Pascal completely unsuited to writing allocators, buffered IO, and other OS internals. ... Maybe there's a lesson there.

Rust lets you do explicit type casting and write `unsafe` blocks in situations where you absolutely need to dereference raw pointers or do pointer arithmetic.[2] It lets you create null pointers or mark pointers as non-null. But not all code needs to do that. In Rust, you can isolate the code that does from the rest that doesn't.

[1] https://thanks.rust-lang.org/

[2] https://doc.rust-lang.org/std/ptr/index.html


This is like saying "who raised their hand and asked for a language where any number of trivial mistakes allowed by the compiler will lead to massive security holes?"

No one, and yet we have C and people use it. No one "asks" for the disadvantages of a given language, they are just trade-offs in exchange for some advantages.


The reason people use systems programming languages is because they need to efficiently and effectively manage and manipulate memory. That's why C was created in the first place - to write the 100,000+ lines of code that would become Unix Version 4 in 1973. (Not bad for a two year old language.)

Which means that when you present me with a systems programming language that enforces an ownership concept that makes it much more difficult to write allocators or even doubly linked data structures, and then use that language's existence to justify adding the same restrictions into a version of C, "who asked for this?" might well be the least offensive response I can muster.


C makes it difficult to write allocators and doubly linked lists too. It doesn’t yell at you when you make them, but they are difficult to write nonetheless, because we see that it’s easy to write incorrect code if you’re not very, very careful.


> The reason people use systems programming languages is because they need to efficiently and effectively manage and manipulate memory.

That's not true. Assembler and machine code predate C. And do the job much more effectively/efficiently.

For example Menuet OS an OS in pure assembly has like 2MiB and has stuff like GUI, graphics, etc. What Linux does in hundreds of MiB.

But they need to rewrite it for each hardware platform.


None of this matters unless it is universally applied. Requires a new language and ecosystem around it.


I have a hard time understanding what's going on here.

Isn't that just some sort of static analysis?


“Crust” was right there, and you didn’t go for it.


They missed the opportunity to call it “crusty”


"Crust of Rust" is already a thing. https://youtube.com/@jonhoo


Wow I was literally thinking about this idea yesterday.

It’s a great idea I hope it catches on.


although this comment doesn't add anything to the conversation, i find the downvote a bit harsh. I think anybody experience this surprise of seeing someone else have the exact same idea as ours at some point.

Then after a bit of time one realize zeitgeist is a super powerful thing and accepts the idea that "having a great idea" isn't something that exceptional nor valuable. Implementing the idea is.


A missed chance to call it "C-rust-y" =)


Or “crust.”


[flagged]


Man replaces seatbelts with t-shirts with seatbelt print. Wonders why people react.


tell us more. please enlighten us


[flagged]


I heard that systems programming used to be dangerous and scary but then Rust was invented so now its okay.


how Rust will challenge the ethical issues in C? i.e.: - addictive design - corporate ownership of data - algo bias - weak cyber security - overemphasis on features Not saying C has all of them. Just let's use these issues as an ethics compass to discuss?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: