5 ms·
> Aborting the program on integer overflow seems so drastic. Disagree. Overflowing of a signed integer type is undefined behaviour, which deserves to be taken
by MaxBarraclough 6y ago
> Aborting the program on integer overflow seems so drastic.
Disagree. Overflowing of a signed integer type is undefined behaviour, which deserves to be taken seriously.
I was surprised to see that the article doesn't mention the signed/unsigned distinction, or undefined behaviour. Overflowing of a unsigned integer type is not a problem, it's defined to wrap around, and may be done intentionally.
- UncleMeat 6y ago> Overflowing of a unsigned integer type is not a problem, it's defined to wrap around, and may be done intentionally. It is not a problem for the language, but it may be a problem for your program. Unsigned overflow can happily introduce vulns into your bounds checks.
- scoutt 6y agoI guess people overreact to "undefined behavior". If your software runs always on the same platform then you can know what the behavior would be. It might also be intentional and should not crash your program. Undefined behavior is used when doing a specification for a compiler that will be used in many architectures and they cannot clearly specify what would happen on ALL architectures for a given operation, because the result might change among these architectures. Undefined behavior doesn't mean that your CPU has either a chance to suddenly blow away or that it would gain self-awareness and destroy the world. You can actually predict what would happen if you throw away a rock on earth. You cannot predict it for every planet in the universe, so theoretically "throwing a rock" produces undefined behavior.
- jjnoakes 6y ago> If your software runs always on the same platform then you can know what the behavior would be. This is not necessarily true, and I consider it to be a harmful misconception. I think people under-react to "undefined behavior". What you think the platform would do if you overflowed an integer using machine instructions and what your C or C++ code ends up executing can be wildly different things because C and C++ compilers do everything in their power to optimize your code assuming your signed integers will never overflow. If they do, who knows what state your program is in or which machine instructions the compiler would have scheduled.
- scoutt 6y agoYou are right. I might correct the sentence with "you can often know". Undefined behavior should be avoided but really is not that terrible.
- jjnoakes 6y agoWe will have to agree to disagree. Fully understanding what a program might do if there is undefined behavior is not trivial. It requires basically reviewing and fully understanding the output assembler for every single build. Any change in system headers, compiler version, compiler flags, or source code might invalidate previous reviews. And programs with lurking undefined behavior may not seem dangerous but sufficiently clever exploits can do quite amazing things with the smallest of attack surfaces.
- scoutt 6y agoSure but in 17 years writing C for a living, with lines of code by the millions, and (embedded) devices running my code all over the world I still have to know about an integer overflow bug. Sure, I don't always write bug-free code (as anyone), but when I say it's not so terrible I mean that UD should be considered a rare case, and it's not worth even a single night of quiet sleep, let alone switching languages or overreacting. Hey, I am more afraid of a flipping bit due to power supply noises. And I don't want to say either that my code is perfect, or since it never happened to me it will never happen to you and that you can go around triggering UD everywhere since it's not a big deal. But I also like to warn young players that "boooo UD!" is just part of a FUD tactic for them to adopt some shiny new language.
- fbkr 6y agoThis is not correct, what you are thinking is implementation defined or maybe unspecified behavior. Please do explain the behavior of calling an uninitialized function pointer on x86 if you insist.
- MaxBarraclough 6y agoAs jjnoakes and fbkr already commented, this account of undefined behaviour is not correct. You've conflated it with unspecified behavior and implementation-defined behavior, and they're not the same beast. [0] Undefined behaviour does not mean that the behaviour simply depends on your platform and is otherwise harmless. That's a widespread misconception, and a rather harmful one. You may see that a signed integer overflow appears to wrap harmlessly on your platform, but the compiler is under no obligation to consistently handle signed integer overflow in this way, unless its own documentation makes this guarantee. > people overreact to "undefined behavior" I have to agree with jjnoakes that people more commonly underreact to it. > If your software runs always on the same platform then you can know what the behavior would be. You cannot infer what non-standard guarantees your compiler is committed to. Unless the compiler guarantees to handle UB in a certain way, it is free to surprise you at any time. > It might also be intentional As mentioned above, intentional UB only makes sense if the compiler guarantees to give you the expected behaviour. If that's not the case, it's a bug. Even then, it's probably best to write portable standards-compliant code. Either way I'd hope to see a static-assert checking that the expected compiler is being used, loudly breaking the build if this check fails. > should not crash your program. This isn't the case. Dereferencing NULL may cause a segfault, terminating your process. Dividing by zero might cause a similar kind of explosion. Depending on platform, freeing a pointer twice might also immediately crash the program (the most helpful way for a platform to handle a double-free). > Undefined behavior is used when doing a specification for a compiler that will be used in many architectures and they cannot clearly specify what would happen on ALL architectures for a given operation, because the result might change among these architectures. Not always. The C rule about data-races being undefined behaviour, is intended to enable compiler optimisation, by permitting compilers to assume the absence of data-races. This rule would make sense even if C weren't intended to be portable across different hardware architectures. > Undefined behavior doesn't mean that your CPU has either a chance to suddenly blow away In principle, undefined behaviour could result in hardware damage, but this seems pretty unlikely unless you're writing power-management code for a motherboard, or something like that. Of course, if you're writing code for a medical system, industrial-control system, or avionics, then undefined behaviour might have terrible consequences. Self-awareness would be permitted by the C standard, but, again, rather unlikely. > You can actually predict what would happen if you throw away a rock on earth. You cannot predict it for every planet in the universe, so theoretically "throwing a rock" produces undefined behavior. I don't see much value in this analogy. It's possible to build a fully deterministic programming language, with no undefined behaviour, and no platform-specific variation. C isn't designed that way, but this is a property of C, not a general fact of computation. It's also possible to write C code entirely devoid of undefined behaviour. [0] https://stackoverflow.com/a/4105123/ https://stackoverflow.com/a/4105123/
- R0b0t1 6y agoAre you sure? IIRC overflow or underflow is always UB per the (earlier?) C standards; they did not expect a single popular representation system for numbers.
- MaxBarraclough 6y agoYes, I'm quite sure. C mandates that unsigned integer types use the typical binary representation, and it mandates wrapping arithmetic. I don't know much about the early C standards, it's possible it wasn't always this way. https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152052 https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pa... https://stackoverflow.com/a/18195756/ https://stackoverflow.com/a/18195756/
- masklinn 6y agoYou’re you’re talking about the behaviour in C. Other langages are not C and can and do define other behaviours. Overflow is neither wrapping nor UB in Swift, it’s an error. Overflow is never UB in Rust but it might be wrapping or a panic. Overflow doesn’t exist in Python or Erlang. I think overflow is IB in Haskell. You get the point: that signed overflow is UB and unsigned wraps in C has no bearing on what other langages do. Swift traps on overflow, regardless of signedness.
- MaxBarraclough 6y agoThis thread is about C++.
- masklinn 6y agoThis sub-thread's starting point was literally a comment on Swift's behaviour. Unless C++ has drastically changed and now abruptly aborts on overflow.
- MaxBarraclough 6y agoI think you have this confused with the subthread under alblue's comment.