top | item 43971317

(no title)

thasso | 9 months ago

> The worst part about uninitialized variables is that they frequently are zero and things seem to work until you change something else that previously happened to use the same memory.

This is not the whole story. You're making it sound like uninitialized variables _have_ a value but you can't be sure which one. This is not the case. Uninitialized variables don't have a value at all! [1] has a good example that shows how the intuition of "has a value but we don't know which" is wrong:

  use std::mem;
  
  fn always_returns_true(x: u8) -> bool {
      x < 120 || x == 120 || x > 120
  }
  
  fn main() {
      let x: u8 = unsafe { mem::MaybeUninit::uninit().assume_init() };
      assert!(always_returns_true(x));
  }
If you assume an uninitialized variable has a value (but you don't know which) this program should run to completion without issue. But this is not the case. From the compiler's point of view, x doesn't have a value at all and so it may choose to unconditionally return false. This is weird but it's the way things are.

It's a Rust example but the same can happen in C/C++. In [2], the compiler turned a sanitization routine in Chromium into a no-op because they had accidentally introduced UB.

[1]: https://www.ralfj.de/blog/2019/07/14/uninit.html

[2]: https://issuetracker.google.com/issues/42402087?pli=1

discuss

order

chipsrafferty|9 months ago

The unsafe part is supposed to tell you that any assumptions you might make might not hold true.

gingerBill|9 months ago

> You're making it sound like uninitialized variables _have_ a value but you can't be sure which one.

Because that's a valid conceptualization you could have for a specific language. Your approach and the other person's approach are both valid but different, and as I said in another comment, they come with different compromises.

If you are thinking like some C programmers, then `int x;` can either have a value which is just not known at compile time, or you can think of it having a specialized value of "undefined". The compiler could work with either definition, it just happens that most compilers nowadays do for C and Rust at least use the definition you speak of, for better or for worse.

nlitened|9 months ago

> C programmers, then `int x;` can either have a value which is just not known at compile time

I am pretty sure that in C, when a program reads uninitialized variable, it is an "undefined behavior", and it is pretty much allowed to be expected to crash — for example, if the variable turned out to be on an unallocated page of stack memory.

So literally the variable does not have a value at all, as that part of address space is not mapped to physical memory.