HNHacker News
TopNewBestAskShowJobs

veddan

208 karma · joined December 13, 2013

submissionscomments
veddan··on Rust, Lifetimes, and Collections
Checked array access is implemented with unsafe code.

Actual code implementing the `[]` operator for arrays ("slices"):

    fn index(&self, &index: &uint) -> &T {
        assert!(index < self.len());

        unsafe { mem::transmute(self.repr().data.offset(index as int)) }
    }
By having `unsafe {}` it's possible to build low-level functionality as libraries rather than in the compiler. There no reason to think that code such as this would be less prone to bugs if it were hard-coded into the compiler. I'd be more inclined to believe the opposite.
veddan··on Rust, Lifetimes, and Collections
> By avoiding privileged optimizations in the frontend and by giving programmers low-level tools where they need them, Rust empowers library authors to get things done without having to bug the Rust developers themselves to implement them.

And there are cases where it is desirable to use unsafe indexing (beyond implementing the standard library iterators). While LLVM is able to get rid of nounds-checking for a simple indexing loop, it's less likely to do in other circumstances. For example, a high-performance sorting function might want to use (some) unsafe indexing. The access patterns and loop exit conditions can be very complex, and LLVM will not be clever enough to reliable optimize out bounds checks.

veddan··on Rust, Lifetimes, and Collections
In most cases, you use iterators rather than indexing

    for x in v.iter_mut() {
        // do some work with x
    }
or if you need the index

    for (i, x) in v.iter_mut().enumerate() {
        // do some work with x and i
    }
similar to Python's enumerate(). These loops never need to do any bounds-checking, even when compiling without optimization.

In this example the iteration count is a small compile-time constant (5), and the loop body is small, so when compiling with optimizations the loop will be unrolled.

veddan··on Rust, Lifetimes, and Collections
If we take your code and modify it so that the compiler can't just get rid of the array acces, we get:

    extern crate test;

    fn main() {
        let mut v = vec![1i32, 2, 3, 4, 5];
        let vlen = v.len();
        for i in range(0, vlen) {
            let x = &mut v[i];
            test::black_box(x);  // do some work with x
        }
    }
Compiling this file with rustc -O, the compiler not only gets rid of the bounds checking, it gets rid of the loop altogether by unrolling it completely.

LLVM IR: https://gist.github.com/veddan/1535a8718cf2c85006ea

veddan··on The Design of the Connection Machine (1994)
Also, the CM-5 moved away from the hypercube topology of the CM-2 to a fat tree.
veddan··on Learning Rust
>Rust does not use reference-counting GC. Instead, it has a fairly unique borrow checking system for garbage collection, which not only handles cleaning up memory but also cleaning open sockets, file handlers, etc. There is a generic type implementation of a reference counted variable you can use, though.

Rust does not have garbage collection, unless you count using types like Rc<T> garbage collection. It has destructors, just like C++, and uses them for cleaning up resources like file handles and memory. Lifetimes do not really interact with destructors. They're part of the type system and do not have any effect on the generated code.

veddan··on Stack unwinding in Rust
It's not just a matter of the compiler missing optimizations. Some (unsafe, low-level) algorithms have to be written differently (and less efficiently) because of the possibility of unwinding. Disallowed patterns typically look something like

  * Put an object in an invalid state
  * Perform some operation that might unwind
  * Fix the object again
If you unwind while the object is in an invalid state, and its destructor is called during unwinding, you can end up with undefined behavior.
veddan··on Stack unwinding in Rust
Unwinding through C is undefined behavior, so a Rust function called from C must catch all exceptions and (preferably) return an error code to the C caller.
veddan··on Apocalypse soon: the scientists preparing for the end times
I'm sure a similar argument could be made about many human activities.
← PreviousPage 2 of 2