When should we mark our functions unsafe?


#1

[does this fit better on internals.rust-lang.org?]

When should we mark our functions unsafe? What’s the rule of a thumb about what’s safe? What’s the official recommendation on exposing unsafe functions from a crate? Is this discouraged at all?

I see one usecase in which unsafe exported functions make sense: interfacing with ptrace. Some of its routines, such as PTRACE_POKEDATA are unsafe by design (in my meaning of unsafe). They can very easily crash the traced process, for example by writing (or reading in PTRACE_PEEKDATA) to a disallowed location. OTOH, that’s basically what they are for - for writing arbitrary data in an arbitrary location, so there’s basically no way to make them unconditionally safe.


#2

Nope! Internals is about developing rust itself, users is about using Rust. This question is a perfect post here.

Any time that calling the function could introduce memory unsafety. “Memory safety” is the absence of “data races.” Data races are: https://blog.regehr.org/archives/490

A data race happens when there are two memory accesses in a program where both:

  • target the same location
  • are performed concurrently by two threads
  • are not reads
  • are not synchronization operations

In some sense yes, and in some sense no. Exposing safe interfaces is preferred, but sometimes, you have to expose something that’s unsafe. That’s not an inherently bad thing.

Yup! So they’d still be unsafe. It’s just a fact of life.


#3

Or any time calling it can directly crash, e.g. by attempting invalid reads/writes, or violate internal invariants, which can later lead to invalid reads/writes. (For example, str::from_utf8_unchecked.)