Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I'm not sure i think those situations are comparable. If a rust func is taking an Option<t>, its essentially advertising that it can handle None values. That feels quite a bit different from giving a c function a null pointer and having it freak out.
 help



Ye, sure, but Rust won’t compile a `foo(std::ptr::null())`, if the function is defined as `fn foo(b: &Baz)`. C doesn’t get that luxury. That is the point of the article.

  $ gcc -Wall -Werror -x c - << EOF
  void f(int x[static 1]){}int main(){f(0);}
  EOF
  <stdin>:1:37: error: null passed to a
      callee that requires a non-null argument
      [-Werror,-Wnonnull]
    1 | void f(int x[static 1]){}int main(){f(0);}
      |                                     ^ ~
  <stdin>:1:12: note: callee declares array
      parameter as static here
    1 | void f(int x[static 1]){}int main(){f(0);}
      |            ^~~~~~~~~~~
  1 error generated.
It can be done, though it usually isn't.

Can you do that with a dynamic array? If not, it's pretty severely limited (unless you mean that literally forbidding dynamic memory is usually not done, which I guess it's true outside of some embedded code but not a particularly meaningful statement).

`int x[static 1]` isn’t exactly intuitive when one wants to define a reference to an integer. Nor is this practical given a dynamic array of integers. Or a single integer field in a struct.

But it isn't different, that's Tony Hoare's Billion Dollar Mistake.

It seems like you're pretty fundamentally misunderstanding what the mistake is, because you have it backwards. Null is a problem because you can just use it like any other pointer without having to explicitly decide how to handle if it's null; Option does not have this problem because you have to explicitly decide how to handle if it's None. Even if you choose to crash if it's None, that's an explicit operation on an Option itself, not the underlying value. There's no equivalent way to force an explicit decision about handling null; it looks just like every other pointer, which means that the only way to avoid using it like one is to be really careful (which we have decades of empircal evidence showing might as well be impossible to do uniformly).

It's absolutely different: “I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.”

His mistake was making _all_ reference taking functions also accept null. In Rust functions opt into None | Some

This comes up with C# which must have default(T) so references default to null. In Rust there is no general default(T) that must always resolve


My contrast was to "That feels quite a bit different". The type system in C only has Tony's nullable references, you can't say that you don't mean that because it wasn't your choice to make, it's like if some C programmers say obviously they don't mean zero when they take an integer - too bad, C doesn't have the non-zero integers (Rust does, NonZeroI32 for example is the signed 32-bit integers except zero)

It is different. Handling `None` in a way that crashes your program is well defined in a Rust function. If you're using `unwrap` or `expect`, the program will crash with a stack trace and an error, instead of running into undefined behavior.

While it is undefined behavior on the C standard level it a null pointer dereference is guaranteed to trap on most platforms.

Yes. Its also explicit instead of implicit. In rust (and typescript, swift, haskell and others), you have to opt-in to nullability. By default, functions can't take a null in place of a non-nullable value. And whether a function accepts a T or an Option<T> is part of the signature.



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

Search: