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.
How expensive is integer-overflow trapping in C++?
171–180 of 198 posts
Re: How expensive is integer-overflow trapping in C++?
#172Earlier quoted context omitted.
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, an…
Disagree. UB in C can mean your program silently going off the rails in a way that isn't possible in many other languages. UB really can manifest in bizarre and scary ways on real platforms. [0][1][2][3] If it isn't manifesting that way in your case, that's just good fortune.
> I still have to find a bug or fail a test because some strange UD
I should hope your safety-critical code is not permitted to contain known instances of unintended undefined behaviour. (There can be exceptions where UB is truly intended. JIT compilation always relies on UB, for instance, not that this would apply to safety-critical code.)
If your program contains undefined behaviour, that means that at best, it works by coincidence. Safety-critical code should not work by coincidence, it should be correct by construction (to steal a term from the formal methods world).
Also, it's UB, not UD.
[0] https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=63...
[1] https://cryptoservices.github.io/fde/2018/11/30/undefined-be...
Re: How expensive is integer-overflow trapping in C++?
#173Earlier quoted context omitted.
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…
Firstly, says who? The first implementations of C, or its predecessor, by Dennis Ritchie, compiled into threaded code: sequence of function calls. He simply wanted to work at a higher level than assembler.
Secondly, which optimizations?
Optimizations like "this loop must be infinite because i is incremented from 0 and going past INT_MAX would be undefined behavior; and therefore the code after is unreachable and can be deleted" are not in "vital" in any shape or form.
That kind of thing points to the work of an ego that took the shortest possible career path into becoming a compiler committer, long before acquiring the required maturity.
> It doesn't intend to hold your hand
Modern C compilers are crossing from the "not holding your hand" territory into "knocking a tool out of your hand" territory.
> It's a good thing that compilers are capable of deep inlining and removing code that is dead for a given context.
Removing code because of "if the behavior of prior code was written by a perfect programmer who follows ISO C to the letter, this line cannot be reached" is definitely not a good thing.
Removing code because of some constant expression, or expression that is always true doe to type (like x < 0, x being unsigned) is certainly a good thing.
Re: How expensive is integer-overflow trapping in C++?
#174Earlier quoted context omitted.
Thanks for answering about unsigned numbers. I don't believe Rust is anything like Swift. Do you think that by "like Swift" it just meant "languages where an overflow will result in the program aborting its execution"? If so then that was a pretty useless tautology. (I had assumed it meant something like "like Java" meaning any language that uses the JVM.)
> I don't believe Rust is anything like Swift. Do you think that by "like Swift" it just meant "languages where an overflow will result in the program aborting its execution"? That's literally the sole and entire subject of the article, what else would it mean? > If so then that was a pretty useless tautology. The wording is odd but it's a useful classification because it's an extremely uncommon behaviour. > I had as…
Something like "this thing is true about those languages where it's true" would be a totally worthless thing to say: it communicates zero actual information. It doesn't even say there actually is any one language (apart from Swift itself) that satisfies it. Why would the article include an empty statement like that? Even if it's conceivable that it does, surely it's reasonable for me to ask if there's an alternative interpretation that actually had some useful meaning?
> what else would it mean?
It could be that "languages like Swift" refers to a collection of related languages which are pretty obvious if you're familiar with them regardless of this overflow stuff. That is actually the more obvious interpretation to me, because saying that they all share the same overflow behaviour would be meaningful non-trivial information.
I think that's a reasonable thing to think given that "language like X" makes sense for a lot of languages. Maybe Java wasn't the best example, but if someone said "lisp-like" languages or "JavaScript-like languages" you might have an idea what they mean. As I said, I'm not familiar with Swift so for all I know "Swift-like" could make sense too. But it raises the question: what languages would that phrase include? That's why I asked.
Re: How expensive is integer-overflow trapping in C++?
#175Earlier quoted context omitted.
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, an…
The point is to eliminate it because it can cause problems in even the most well-tested code, either when the code inevitably operates outside the test parameters or when compilers or compile flags or system headers change.
Eliminate it both reactively and protectively. Not only in your own code, but encourage others to do the same.
Re: How expensive is integer-overflow trapping in C++?
#176Earlier quoted context omitted.
> 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…
> C is intended to run terribly fast, so optimisations are vital. Firstly, says who? The first implementations of C, or its predecessor, by Dennis Ritchie, compiled into threaded code: sequence of function calls. He simply wanted to work at a higher level than assembler. Secondly, which optimizations? Optimizations like "this loop must be infinite because i is incremented from 0 and going past INT_MAX would be undefi…
Well, the modern software world. Performance is one of C's great advantages. Poorly optimising C compilers do exist, such as obscure compilers targeting obscure architectures, but much C code is written for speed. Kernels and game-engines are written in C and C++ partly for performance reasons.
(Although, again, it's not as if we have to keep using C. Much safer alternatives do exist that don't have significant performance penalties, and it's a pity they don't get more traction.)
> Optimizations like "this loop must be infinite because i is incremented from 0 and going past INT_MAX would be undefined behavior; and therefore the code after is unreachable and can be deleted" are not in "vital" in any shape or form.
I believe the assumption of no UB can be important in auto-vectorisation, a very significant optimisation.
There's a quantifiable performance advantage to any optimisation. The compiler vendors found it worth pursuing, so there must be something to it. These optimisations can be disabled, but this will harm performance.
As to whether it's 'worth it', that's a matter of opinion. I still think that if you want a safe language, you should just use a safe language. C is not a safe language, and isn't trying to be. Even without these specific optimisations, there are still plenty of other ways buggy C code can still cause havoc. The only way to properly tame C is with projects like ZZ and Armada, as I previously linked.
> That kind of thing points to the work of an ego that took the shortest possible career path into becoming a compiler committer, long before acquiring the required maturity.
It's not reasonable to diagnose an engineering decision as a personality disorder. Also, I believe most of these decisions were made by committee, but I'm not well read on C's early days.
They decided to make C the kind of language that places a great burden on the programmer, regarding subtle errors. We agree that this is a real downside of the language, but it's not without its advantages. C is the gold standard for performance, and has been for decades. The presence of UB has probably been somewhat helpful to that end, and has also helped C's portability.
(Again though, modern compilers can optimise Ada very effectively. With modern compilers, I don't think C's UB is all that advantageous for performance.)
> Modern C compilers are crossing from the "not holding your hand" territory into "knocking a tool out of your hand" territory.
That's a rather good metaphor for aggressive optimisers. I'm reminded of a comment on programming languages: C treats you like an adult. Pascal treats you like a child. Ada treats you like a criminal.
> Removing code because of "if the behavior of prior code was written by a perfect programmer who follows ISO C to the letter, this line cannot be reached" is definitely not a good thing.
> Removing code because of some constant expression, or expression that is always true doe to type (like x This strikes me as a distinction without a difference. It's the same optimisation: elimination of unreachable code. The compiler is always permitted to assume absence of undefined behaviour, that's how undefined behaviour is, well, defined. If there's any UB present in an execution at all, all bets are off. I think you're suggesting a different approach would be better, but I'm not sure what you're proposing.
We could try to define a language similar to C but devoid of undefined behaviour. Part of the spec could be adjusted to use indeterminate values instead, such as for signed integer overflow. We could define divide-by-zero as instantly terminating the process. (The C++ language takes this approach very occasionally, [0] but defining things this way is troublesome for embedded systems compilers.) This language wouldn't be as easy to compile, though. Features like C's unsafe pointer arithmetic, and unsafe function pointers, seem hard to sanitize. I wish I knew Ada better for comparison.
Re: How expensive is integer-overflow trapping in C++?
#177Earlier quoted context omitted.
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, an…
> Especially is not something to be afraid of. Disagree. UB in C can mean your program silently going off the rails in a way that isn't possible in many other languages. UB really can manifest in bizarre and scary ways on real platforms. [0][1][2][3] If it isn't manifesting that way in your case, that's just good fortune. > I still have to find a bug or fail a test because some strange UD I should hope your safety-cr…
> I should hope your safety-critical code is not permitted to contain known instances of unintended undefined behaviour.
It's not.
> Also, it's UB, not UD.
Now that you mention it I checked my other comments I wrote from my phone and noticed it changed UB with UD.
Re: How expensive is integer-overflow trapping in C++?
#178Earlier quoted context omitted.
> C is intended to run terribly fast, so optimisations are vital. Firstly, says who? The first implementations of C, or its predecessor, by Dennis Ritchie, compiled into threaded code: sequence of function calls. He simply wanted to work at a higher level than assembler. Secondly, which optimizations? Optimizations like "this loop must be infinite because i is incremented from 0 and going past INT_MAX would be undefi…
> says who? Well, the modern software world. Performance is one of C's great advantages. Poorly optimising C compilers do exist, such as obscure compilers targeting obscure architectures, but much C code is written for speed. Kernels and game-engines are written in C and C++ partly for performance reasons. (Although, again, it's not as if we have to keep using C. Much safer alternatives do exist that don't have signi…
No it isn't, because in the one case, if you don't eliminate the code, it turns out to be reachable. The reason is that the logical predicate by which it was deduced to be unreachable ("the program is perfectly written and doesn't invoke undefined behavior") is not actually true.
So that is to say, this code will actually terminate due to wraparound past INT_MAX "for (i = 0; i >= 0; i++);" and statements which follow it are reached. That same compiler has wraparound behavior for int.
It's not the same as "if (1) return;" where the basis for removing the subsequent code is simply true.
Re: How expensive is integer-overflow trapping in C++?
#179Earlier quoted context omitted.
> Aborting the program on integer overflow seems so drastic. Say you do that in a server program. Then convincing it to overflow an integer somewhere (possibly somewhere where it is harmless) causes denial of service and all unrelated connections in the process die? If you don't abort then you probably have an arbitrary code execution vulnerability. Overflow is undefined behaviour in C++, your code is in an unanticip…
> If you don't abort then you probably have an arbitrary code execution vulnerability. There are some patterns in which that is totally true, for example if an integer product is passed to malloc or realloc. Those cases tend to get extra scrutiny in security reviews because it is a well known class of issues. However, it is certainly not the case that every case is exploitable.
Re: How expensive is integer-overflow trapping in C++?
#180Earlier quoted context omitted.
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/j…