Comment by gavinray

1 day ago

Rust protects you from external file data you read being incorrect?

That's one hell of a language!

The code would have failed because you can't use an uninitialized variable, so you would have had to set it to a default. You don't just get random garbage from the stack.

  • You can write a genuine uninitialized local variable in Rust, it's just that you wouldn't do it out of laziness because while in C that's the default in Rust it's a lot of extra work to say "No, I really don't want to initialize this variable" and Rust is like "I mean, if you insist, all I can do is warn you that's a terrible idea".

      int k;  // C makes an uninitialized variable named k - probably bad idea
    
      let k: i32 = unsafe { MaybeUninit::uninit().assume_init() };  // Rust, same bad idea
    

    If we say "I will initialize it - later" that's fine in Rust and you just write the name (and where appropriate type) of the variable and go about your day. The compiler will reject your program if, in fact, it can't see why you're fulfilling that promise, and sometimes that might be because the compiler is dumb (but often it's because you are) but there's no problem technically with this and if the compiler agrees that we do, in fact, initialize it later then it compiles and works and everybody is happy.

    But to actually make a variable and not initialize it, as we saw above, is a lot of extra work in Rust because like... that's a bad idea, why would you be setting out to do that?

    This is such a bad idea that Rust's unsafe std::mem::uninitialized, which is how they did this before MaybeUninit existed, was de-fanged (giving it poor performance by actually writing a pattern to RAM every time) and deprecated so you get a warning if you try to use it even though it was already marked unsafe. See, people (and I'm sure many C programmers are like this) tend to imagine it's OK for say an integer to be uninitialized because surely any possible value is OK, right ? Nope. Your operating system knows that data was never written, and so it feels entitled to fuck you about if you expect it to stay unchanged, because it never promised that will work - as a result rarely but sometimes you get kicked in the head by the OS and you get a seemingly impossible bug.

It would have forced you to either specify a default or fail pretty loudly as soon as you launched the game, both much better than leaving a bug there just for it to resurface 20 years later.

Most popular languages would prevent this. In this case it’s as simple as having more sensible reader API than sscanf in standard library and forcing variables to be initialized.

Of course not, but this here was a memory access error and rust would have prevented this.