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

This is certainly an interesting argument for making certain behavior (in this case, uninitialized access) the default and UB. There’s a similar argument for making signed overflow UB instead of defined to wrap, even if you’re only targeting two’s-complement machines, that is: leaving the behavior undefined enables analyzers to detect the behavior and making it the default can make otherwise silent errors detectable across all programs. I think I’ve come around to wanting these to be undefined and the default, it’s unintuitive but defined wrapping or zero initialized may be undesirable behaviors anyway.


The dangerous behavior should be opt-in, not opt-out. I appreciate that C gives you all of these neat footguns but they need to be hidden to find for only those who need them. Stuff like implicitness being the default for functions, int wrapping, and non-initialized variables just give rise to bugs. And for what? So first-year students can have their unoptimized code be 0.00001% faster by default? It's dumb.


If it’s opt-in then code written for the default (ie most code that wasn’t written to use the unintuitive behavior for some performance reason) will be either well-formed code that relies on the behavior (fine, but for signed int wrapping this is rare, for zero init this is common but not always the case) or ill-formed code that subtly fails (e.g. no check for overflow or zero is an invalid value). The code that is ill-formed cannot be checked by present or future static or dynamic analyzers, since the failure condition (signed overflow or access before assignment) is _defined to be something valid_ thereby preventing analyzers from determining whether the programmer intended the signed arithmetic to overflow or not, or for that value to be zero or not, etc.

Hopefully I’m communicating why it is useful to leave the default behavior undefined or invalid. It doesn’t really have to have anything to do with performance, signed wrapping is no less performant on two’s-complement machines (barring compiler optimizations enabled by assuming no overflow) since it is the result produced by add instructions on overflow. The benefit is that it enables instrumentation and analyzers to detect this behavior because it is known to be invalid and not something the programmer intended.

As an analogy, consider what would happen if you defined out of bounds array access to be _something_, now analyzers and instrumentation cannot detect this as an error, since the programmer may have intended for whatever that defined result is to occur in that case.




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

Search: