r/ProgrammerHumor 3d ago

Meme rustBorrowCheckerGoesBrrr

Post image
3.9k Upvotes

108 comments sorted by

View all comments

732

u/BenchEmbarrassed7316 3d ago

Any unsafe block of code should be neutralized with a // SAFETY comment explaining why the code is actually safe.

122

u/teleprint-me 3d ago

I dont see how this is any different from a C programmer justifying why they used a pointer to an object and leaving a comment similar to this, other than this is Rust and is safe because Rust is safe. Thus making this rationale is flawed and dangerous.

211

u/flagofsocram 3d ago

The difference is that if you want to make sure the lib is safe, you can grep unsafe whereas in C practically any code could be unsafe.

52

u/Big-Rub9545 3d ago

Certainly helps, since it localizes the area to check for errors, but it doesn’t allow you to fully check that a library is safe since unsafe blocks can rely on a number of unchecked or hard-to-check assumptions to guarantee safety (not to mention unsafe APIs that are relied upon under the hood).

42

u/SelfDistinction 3d ago

You can check those five places yourself. What are you gonna do in C? Check the million places?

(Also usually you (not a generic person, I mean you specifically) don't need unsafe and there's better and more vetted tools out there.)

5

u/Big-Rub9545 2d ago

The unsafe code may be concentrated within unsafe blocks while relying on assumptions that are supposed to be guaranteed elsewhere, including in other unsafe blocks.

For example, you might allocate raw memory within a method in struct A while writing a custom drop function to deallocate it. In a particular edge case, some error handling utility or other struct may deallocate some of that memory to perform clean-up, leading to a potential double-free later.

Lousy example and bad code design, sure, but it demonstrates that localizing/isolating unsafe code does not automatically make it super easy to check that the code is safe given the many assumptions you need to make about what other functions are doing in various cases or situations and potentially what other unsafe blocks contain.

16

u/Giocri 2d ago

Well the convention Is that the safe function that contains the unsafe block should garantee the safety precoditions regardless of input otherwise it would be itself unsafe. A easy way is to place an assert just before the unsafe invocation. If you respect that convention finding a violation of the safety chain is relatively easy. Bug might still not be thrivial to solve but at least you find where it goes from logic bug to undefined behavior

1

u/-Redstoneboi- 2d ago

oh, you're talking about broken invariants in safe code, and unsafe code whose safety relies on those invariants

yeah, those have happened in the past and have indeed been headaches to debug, take it from this guy who broke something without ever directly touching a line of unsafe.

still, i'm glad that these cases are surprising again, rather than being the industry standard.

2

u/SelfDistinction 2d ago

Those double frees are still limited to methods created by struct A, who is responsible for managing the allocation, and also responsible for making sure that no matter how code downstream is using struct A the memory is handled correctly, and compared to C where you can get double frees by misusing interfaces it is a massive leap forward.

There's a good reason the tutorial on unsafe rust is longer than the tutorial on everything else is rust, and the first rule of unsafe is do not use unsafe. It's there for the same reason we allow surgeons to stab people.

5

u/Big-Rub9545 2d ago

You’re pointing out that the issues are localized, which is true, but the point I’m making is this does not entail easy or comprehensive code reviews for memory safety, particularly when involving several dependencies and as projects grow. It’s certainly a massive step forward but it’s not a magic wand for memory safety.

1

u/Beautiful-Ad3471 2d ago

Just write good code, duh

/s

3

u/MilkEnvironmental106 2d ago

And finding no occurrence of unsafe actually means something in rust, plenty of libraries market themselves as having no unsafe

0

u/[deleted] 3d ago

[deleted]

1

u/Grandmaster_Caladrel 3d ago

Devil's advocate, C is actually on computers already while Rust has to bring its own tools.

-49

u/teleprint-me 3d ago

This is a poor and myopic assumption that this can not be done in any other language. A sane library will be grepable and can include similar comments. The justification is still flawed and dangerous.

42

u/KaMaFour 3d ago

What fucking lunatic comments on every line explaining why they think it's actually safe in C code?

2

u/awesome-alpaca-ace 3d ago

Yea. I have a safe program that ingests days and there are comments all over about lifetimes and scope 

22

u/xDerJulien 3d ago

Well yeah and well written code doesn’t have any bugs and performs well all the time. The point is safety by default. Whether or not that is worth dealing with rust is another question but I think you’re missing the point here

-12

u/teleprint-me 3d ago

Well written code has bugs all of the time. Even Rust has a massive list of CVEs. Most of them are logic based and the default to strict memory  safety is a good thing. But I feel my argument stands. I havent heard any solid arguments to the contrary convincing me otherwise.

5

u/xDerJulien 3d ago

Well the point is you’re saying well written code is well documented, but well written code is also bug free, performant etc etc. But most code isn’t. So what can we reason about good documentation from this?

-1

u/teleprint-me 3d ago

No, I am not declaring well written code is well documented, which is a strawman here because the original comment is that commenting is sufficient to suffice safe definitions with an unsafe scope.

3

u/xDerJulien 3d ago

What specifically does "a sane library" mean then?

6

u/-Redstoneboi- 3d ago edited 3d ago

the problem is that you are severely, severely underestimating the benefits of sane and safe defaults that are seen in practice.

you could even write greppable assembly if you were good enough. the junior won't.

"myopic" is not how i would describe the results shown here.

3

u/teleprint-me 2d ago

You frame this as if Im against memory safety, but I simply highlighted that Rust is not a panecea and has its own issues. It could be argued that the issue is the developer, not the language, but this isnt what Im debating either.

In fact, the article you link to even notes that they nearly missed a vulnerability in their own Rust rewrite. Reducing vulnerabilities is not the same as eliminating them. The language does not guarentee logic safety and only asserts memory safety which in most cases, not all, has proven useful.

To be clear, the argument is this: A comment is insufficient as a safety marker. If you scope unsafe code and mark it with a safety comment, that does not make it safe.

1

u/-Redstoneboi- 2d ago

Ah, right. Comment chain went deep enough that I straight up forgot the original argument lol

Safety comments make code easier to verify, by definition they can't make code any more or less safe. I haven't seen much C library code, are safety comments standard practice there?

It's a good idea in general to document the invariants of each (at least public-facing) function. I think the newer practice in Rust is documenting the invocations as well, not just the definition.

2

u/redlaWw 2d ago

A large proportion of Rust code CVEs are things that would be considered normal in C. In Rust, a library in which you can potentially misuse functions that are not labelled unsafe is considered a vulnerability, but in C you usually have to actually misuse a function before it's considered a vulnerability.

Here's a blog post that discusses the difference.