Fine, I'll take the 4 byte hit for security and safety critical software then.
Edit: In retrospect, the optimization doesn't actually cause any security or safety problems, because unsafe code can break any invariant, including an enum with a separated tag and value. The particular memory layout of the enum is irrelevant.
Exactly. The correct C for working with what may or may not be a valid file descriptor produces the same machine code as the Rust with Option<OwnedFd>. But, if you mess this up and forget to handle an invalid descriptor the C compiler has no idea and your bug goes unnoticed whereas the Rust won't compile because None isn't Some(OwnedFd).
Edit: In retrospect, the optimization doesn't actually cause any security or safety problems, because unsafe code can break any invariant, including an enum with a separated tag and value. The particular memory layout of the enum is irrelevant.