Live data from Hacker News

How expensive is integer-overflow trapping in C++?

lemire.me

161–170 of 198 posts

Re: How expensive is integer-overflow trapping in C++?

#161
post #126

Earlier quoted context omitted.

> 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.

I 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…

As 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/

Re: How expensive is integer-overflow trapping in C++?

#162
post #157

Earlier quoted context omitted.

From the article: > Looking at the assembly, I find that the clang compiler generates sensible code on x64 processor, with simple jumps added when the overflow is detected. Meanwhile, GCC seems to call poorly optimized runtime library functions.

...because he didn’t pass the correct options to gcc. Look at a comment parallel to yours for details.

I think it was more in response to, "I wish the author had dug a little deeper to see why this slowdown occurs."

Re: How expensive is integer-overflow trapping in C++?

#163
post #153

Earlier quoted context omitted.

We 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 suffici…

Sure 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 ov…

There is a ton of software out there that is riddled with bugs. Much of it is run behind closed doors, isn't exposed to attack vectors like the internet, and happily churns along because no one is trying to attack it.

Lots of other software might be exposed to the internet or to malicious users but no one has stumbled across it and tried to exploit it yet.

Code like that may be ok for now simply because of the circumstances, but I don't think that's a pass to ignore UB or to discourage folks from trying to improve the status quo.

Because some day either the developer of that code, who is used to ignoring this kind of thing, might write some code that has to be more correct or it will get exploited. Or the code itself might get changed, or exposed to attackers, or copied into some other program.

These things happen and they are preventable. And you don't even have to switch languages - turning on sanitizers when you compile and fixing issues as they are found, and encouraging others to do the same, is better (in my opinion) than categorizing folks worrying about and working on this issue - in C and in other languages - as FUD spreaders.

Re: How expensive is integer-overflow trapping in C++?

#164

Earlier quoted context omitted.

Implementation defined means that the behavior is defined. This is patently not what the existing behavior of compilers in the face of integer overflow is.

Every implementation (compiler and arch combo) defines behavior as far as I know, and I’ve tested dozens of combos. What combo does not have implementation defined behavior for C/C++ signed overflow? Are there any?

GCC? Clang? Neither compiler defines it unless you give it flags to specify a certain behavior.

Re: How expensive is integer-overflow trapping in C++?

#165

Earlier quoted context omitted.

C compilers should assume that every bit of code is necessary. The only dead code is that which is predicated on a compile-time constant, as in: if (0) { /* safe to ptimize this away */ } Code which tests a run-time condition must always be assumed to be doing that for a reason. Just provide excellent code generation: great peephole optimizations, jump threading, instruction selection: all the "classics". Try to put…

You're essentially describing a C compiler with advanced optimisations disabled, no? If you want improved safety and fewer footguns, the solution is to use a safer language than C, rather than to try to declaw a fundamentally unsafe language. Even MISRA C fails to guarantee the absence of undefined behaviour. (Other far more involved projects have made this a goal. [0][1]) The obvious candidates are Ada, Rust, and Zi…

It absolutely makes sense to mandate the absence of serious compiler optimizations in an unsafe language, in which programs frequently stray outside of the specification, and in which the programmer has excellent tools for optimizing by hand.

You can write C that is nearly impossible not to generate into a nearly optimal instruction sequence with just basic optimizations that do not try to get clever by with deductions arising from multiple disconnected facts coming from separate statements in the program.

There is a lot of optimization latitude without doing crazy things. You can turn a switch statement into a jump table without causing a problem, for instance. Unrolling loops is fairly safe. You can allocate registers well; you can improve the instruction sequences. You can thread jumps. You can fill branch delay slots.

I don't need the compiler to delete a line of code for me. If I actually delete it myself in the source code, that will shave off just as many cycles!

Now if the compiler would simply warn "that null pointer comparison is being done on a pointer that was dereferenced eralier", that would be useful. Instead of optimizing behind my back, give me diagnostics using which I can change the program to make it faster. I could look at that code and see: by golly, that is right; the pointer is guaranteed not to be null in that code, so we can drop the check. Or, oops, no; that dereference should not be happening before the check!

You can't have compilers guessing about the purpose and intent of disconnected statements in relation to each other, under the assumption that there is no mistake anywhere. Even philosphically, that is stupid.

Advanced optimizations arising from piecing together a deduction from multiple assumptions and facts should all take the form of diagnostic suggestions about how to change the source code.

Re: How expensive is integer-overflow trapping in C++?

#166

Earlier quoted context omitted.

C compilers should assume that every bit of code is necessary. The only dead code is that which is predicated on a compile-time constant, as in: if (0) { /* safe to ptimize this away */ } Code which tests a run-time condition must always be assumed to be doing that for a reason. Just provide excellent code generation: great peephole optimizations, jump threading, instruction selection: all the "classics". Try to put…

The number of people who want the language and compiler implementation you are describing is vanishingly small.

The number of people who are burned because of what implementation they actually have is not so small.

Re: How expensive is integer-overflow trapping in C++?

#167

Earlier quoted context omitted.

Every implementation (compiler and arch combo) defines behavior as far as I know, and I’ve tested dozens of combos. What combo does not have implementation defined behavior for C/C++ signed overflow? Are there any?

GCC? Clang? Neither compiler defines it unless you give it flags to specify a certain behavior.

No, both define it by default on every platform, with no flags needed. Flags allow you to force behavior one way or another.

Here [1], for example, is the output from godbolt demonstrating exactly this. Note there are no flags specified, it produces valid platform specific code, and it does so for every platform listed. You can then set flags if you desire, but there is a default, as I stated.

https://godbolt.org/z/jbY6PM

Re: How expensive is integer-overflow trapping in C++?

#168
post #156
post #153

Earlier quoted context omitted.

Sure 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 ov…

Would you feel the same way when we finally manage to get liability laws for security exploits, like we are now discussing in Germany?

If some of my systems fail, people might die. Should I still be worried for a liability?

Re: How expensive is integer-overflow trapping in C++?

#169

Earlier quoted context omitted.

You're essentially describing a C compiler with advanced optimisations disabled, no? If you want improved safety and fewer footguns, the solution is to use a safer language than C, rather than to try to declaw a fundamentally unsafe language. Even MISRA C fails to guarantee the absence of undefined behaviour. (Other far more involved projects have made this a goal. [0][1]) The obvious candidates are Ada, Rust, and Zi…

It absolutely makes sense to mandate the absence of serious compiler optimizations in an unsafe language, in which programs frequently stray outside of the specification, and in which the programmer has excellent tools for optimizing by hand. You can write C that is nearly impossible not to generate into a nearly optimal instruction sequence with just basic optimizations that do not try to get clever by with deductio…

> It absolutely makes sense to mandate the absence of serious compiler optimizations in an unsafe language

C is intended to run terribly fast, so optimisations are vital. It doesn't intend to hold your hand, so the possibility of surprising consequences from undefined behaviour (subtle programmer mistakes) are permissible under its philosophy.

There'd be little point making C slower without making it safe, that's why no-one has done it.

> You can write C that is nearly impossible not to generate into a nearly optimal instruction sequence with just basic optimizations that do not try to get clever by with deductions arising from multiple disconnected facts coming from separate statements in the program.

That doesn't sound right. Plenty of platform-specific optimisations do not work well at the level of C source code, and for instance cannot be performed by source-to-source optimisers. Generation of prefetch instructions, branch-prediction hinting, auto-vectorisation, computing both division and modulo using a single instruction. C isn't an assembly language.

> If I actually delete it myself in the source code, that will shave off just as many cycles!

It's a good thing that compilers are capable of deep inlining and removing code that is dead for a given context.

> if the compiler would simply warn "that null pointer comparison is being done on a pointer that was dereferenced eralier", that would be useful

We already have linters/static analyzers/compiler warnings for C.

> Even philosphically, that is stupid.

C doesn't pretend to be safe. Annoyingly, it can't really even be effectively checked with runtime checks on debug builds. (It's quite hard work to check against out-of-bounds array access. I believe Valgrind manages it for many cases.) I agree it's a valid criticism of the language given that we don't seem to get all that much in return. Safer languages like Ada can be used for everything C is used for, for roughly zero performance penalty.

Re: How expensive is integer-overflow trapping in C++?

#170
post #153

Earlier quoted context omitted.

Sure 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 ov…

There is a ton of software out there that is riddled with bugs. Much of it is run behind closed doors, isn't exposed to attack vectors like the internet, and happily churns along because no one is trying to attack it. Lots of other software might be exposed to the internet or to malicious users but no one has stumbled across it and tried to exploit it yet. Code like that may be ok for now simply because of the circum…

There are worse things than can happen with bad wrote code other than security bugs. It doesn’t have to necessarily be exposed to the internet or users/attackers for bad things to happen. I truly believe that people just forgot this little fact.

Again, I don’t discourage people from preventing UD, but, again, it’s not a big deal. Especially is not something to be afraid of.

My code is as much as correct, verified, analyzed and tested as possible, and most of the times compliant with the most absurd certifications. Again, I still have to find a bug or fail a test because some strange UD.

Post reply on HN