The unsafe Keyword

  • Turns off some of the compiler checks when applied to a block or function

    • Can call unsafe functions

    • Can dereference raw pointers

    • Can mutate global variables

    • Can use extern Foreign-Function Interface (FFI)

Consequence Of unsafe Abuse

  • Undefined Behavior (UB) when a program

    • Reads uninitialized memory

    • Creates invalid primitive values

      1. Invalid (including null) references or Boxes
      2. bool values that are not either 0 or 1
      3. enum values with bogus discriminants
      4. char values that are not Unicode code points
      5. str values that are not UTF-8
    • Violates the lifetime or sharing rules with references

    • Dereferences a bogus pointer — points somewhere invalid or misaligned

    • Has a data race

    • Unwinds across FFI calls (obscure)

    • Violates standard library (or other) function contracts

  • UB may do nothing, may cause trouble, or may only cause trouble when the optimizer gets clever

Unsafe Function "Contracts"

  • Code should be written so that when properly used UB cannot occur

  • To inform the user of the code, a natural-language "contract" should be written specifying when an unsafe function can be safely called

  • The contract should appear as a rustdoc comment before the function

  • unsafe blocks inside a function must be used in such a way that no valid call to the function can cause UB

  • e.g. from_utf8_unchecked()

Unsafe Block "Contracts"

  • Every unsafe block should have a comment above that describes

    • Need (why is this block here?)

    • Safety (why is this block not UB?)

Raw Pointers

  • Declared for some type T via *const T or *mut T

  • Are essentially just C pointers

  • Safe to do anything other than dereference them

  • Whole bunch of functions in std::ptr and std::mem for dealing with them: Rust has no raw pointer arithmetic.

  • https://play.rust-lang.org/?gist=3467b73129409cade96bc2d4648966ad

  • A raw pointer owns nothing. Watch out for ownership problems

  • Can cast back to a ref with as, but be careful: default lifetime is 'static, while the referenced data probably isn't at all

Examples

FFI

  • Can declare external stuff with extern

  • Watch out for "name mangling"

  • A bunch of stuff in std::os for dealing with C types and values

  • Mostly outside the scope of this course.

  • http://github.com/pdx-cs-rust/mixy

Last modified: Tuesday, 3 March 2020, 5:53 PM