News for hackers. Stuff that matters.
Re:GCC undefined behaviors are getting wild by vgatherps on Monday November 28, 2022 @02:05AM (#33770560)
Somewhat unfortunately this is valid behavior according to the standard. Having to go through walls of text in a standard to prevent the compiler from deleting your security checks because of how you multiplied two integers seems a bit silly.

Having said that I’m of split feelings here. I work in a very performance sensitive industry and on one hand welcomes the ability of compilers to use the knowledge that certain things “can’t happen” to optimize, without me having to always do these optimizations be hand.

On the other hand, there seem to be so many cases like this one where the “undefined behavior code deleter goes brrrrrr” really overextends its usefulness. The “lalalalala standard say I can do this can’t hear you” finger in your ears attitude from compiler maintainers doesn’t help at all either.

I understand that the way much of this works, propagating “poison/impossible values”, can hide the root cause, so you can’t just say “please do the good undefined behavior optimizations but not the bad, so there’s no easy answer. The outcome in the blog post doesn’t feel like a local optimum though, and it’s not the only place I’ve felt that your options are “potentially slow code” or “pray you were perfect enough to not have your program deleted”

Re:GCC undefined behaviors are getting wild by proto_lambda on Monday November 28, 2022 @02:12AM (#33770587)
The problem here is that the thing that "can't happen" isn't actually something that can't happen, it's something that isn't allowed to happen according to a many-hundred-page document that approximately nobody reads. It's not something that can be optimised because the compiler can prove it cannot happen, it is allowed to be optimised because the standard says "dear programmer, if you ever make this happen, god help you".
Re:GCC undefined behaviors are getting wild by pjmlp on Monday November 28, 2022 @02:37AM (#33770756)
Even if someone would read all those pages, constraining ourselves to ISO C only, no way that after an year they would still remeber the about 200 UB cases that are documented there.

Which is why everyone shoulda adopt static analysis tooling and enable all the warnings that are related to UB, pointer and casts misuses.

Many think they know better, it is like those that think builders don't need protection gear at a construction site, it is stuff only for the weak.

Re:GCC undefined behaviors are getting wild by gpderetta on Monday November 28, 2022 @06:31AM (#33772323)
I think implicitly compiler-added runtime check are a more robust and reliable solution than static analysis. For example for pointer dereferences the compiler should could 0-offset dummy load if the load is not guaranteed to be within a page of the pointer. Or adding abort-on-overflow for math. Or bound checking where possible.

It will have a non-trivial cost, but hopefully aggressive optimizations can remove many of these checks (which ironically it is exactly the kind of optimizations people are complaining about) and compilers provide pragmas to disable them when critical.

In a way sanitizers are getting there, but they are explicitly marked as for non-production use which is a problem.

Re:GCC undefined behaviors are getting wild by pjmlp on Monday November 28, 2022 @07:49AM (#33772965)
I agree, but unfortunely that will never happen in most C and C++ circles, just see the heat JF Bastien has been facing for a feature that has been shipping in Windows and Android for the last two years, proven in the battlefield to hardly hinder performance in real use cases.

https://isocpp.org/files/papers/P2723R0.html

Lots of people telling him it will never fly in production, while their Windows and Android phones are using the code that they say isn't good enough.

Re:GCC undefined behaviors are getting wild by gpderetta on Monday November 28, 2022 @08:11AM (#33773179)
Zero initialization is also one of those features that seems such a low hanging fruit to implement...

I'm still moderately optimistic. I suspect that many of these checks will end up being enabled by default on compilers shipped by distros, like stack guards and other forms of hardening.

Re:GCC undefined behaviors are getting wild by josephcsible on Monday November 28, 2022 @02:19AM (#33770629)
I think this view is slightly unfair. I think of UB as the compiler saying "when you promised this thing wouldn't happen, I took you at your word. If bad things happen because you lied, they're your fault, not mine."
Re:GCC undefined behaviors are getting wild by proto_lambda on Monday November 28, 2022 @02:22AM (#33770653)
Lying requires intent. This was a mistake, something that humans are well-known for making, and if the compiler is designed to assume otherwise, it borders on useless in the real world.
Re:GCC undefined behaviors are getting wild by masklinn on Monday November 28, 2022 @02:29AM (#33770692)
A compiler can’t know why you fucked up, it can’t even know that you fucked up, because UBs are just ways for it to infer and propagate constraints.

If an optimising C compiler can’t rely on UBs not happening, its potential is severely cut down due to the dearth of useful information provided by C’s type system.

Re:GCC undefined behaviors are getting wild by eru on Monday November 28, 2022 @02:43AM (#33770792)
> A compiler can’t know why you fucked up, it can’t even know that you fucked up, because UBs are just ways for it to infer and propagate constraints.

To be honest, that's just how compiler writers interpret UB these days.

It's perfectly possible (in principle) to use lots of more sophisticated static and dynamic analysis to recover much of what C compiler just assume. You don't have to restrict yourself to what C's type system provides.

(For an example of what's possible, have a look at all the great techniques employed to make JavaScript as fast as possible. They have basically no static types to work with at all.)

Re:GCC undefined behaviors are getting wild by masklinn on Monday November 28, 2022 @03:04AM (#33770945)
> For an example of what's possible, have a look at all the great techniques employed to make JavaScript as fast as possible. They have basically no static types to work with at all.

I’m sure people will be very happy with a C JIT. That’s definitely what they use C for.

JIT-ed code is full of runtime type and range assertions which bail if the compiler’s assumptions are incorrect.

Re:GCC undefined behaviors are getting wild by eru on Monday November 28, 2022 @03:32AM (#33771123)
Oh, I didn't mean to imply that it would be practical. Only that it's possible and that the type system isn't the only thing you can rely on.

Instead of just assuming that 'x > x + 1' is always true (for signed integers), the compiler could also do the heavy lifting of static analysis (for cases where that's possible).

Re:GCC undefined behaviors are getting wild by littlestymaar on Monday November 28, 2022 @03:41AM (#33771173)
But you talked about JavaScript, where the “heavy lifting” is in fact “assume that it's always true, and switch back a less optimized version if the assumption turns out to be false”. That's exactly the kind of things you cannot do in C, because people use C in contexts were JIT isn't an option.
Re:GCC undefined behaviors are getting wild by eru on Monday November 28, 2022 @03:45AM (#33771200)
Sorry, my general point and my example didn't perfectly match.

For something better matching: have a look at things like Coverity for what you can recover with static analysis of existing C code.

Re:GCC undefined behaviors are getting wild by Gibbon1 on Monday November 28, 2022 @04:32AM (#33771468)
Frankly what I think it we should have a compramize.

Make overflow on a signed int defined. Create a new type called unsafe_int where it is not.

So then the compiler writers get to implement their pointless optimization pit traps. And everyone else can avoid those by banning unsafe_int.

Re:GCC undefined behaviors are getting wild by eru on Monday November 28, 2022 @04:49AM (#33771589)
You can already compile with `-fno-strict-overflow` to get twos-complement overflow for signed integers.

I meant to talk more abstractly about UB in general.

Re:GCC undefined behaviors are getting wild by astrange on Monday November 28, 2022 @05:27AM (#33771858)
The signed integer overflow rule is extremely important for common optimizations, mostly related to loops like knowing if they're finite or rewriting their index directions.

The way to start getting rid of it would be to add for...in... loops or something where the loop index can be a custom no-overflow type.

And "defining" it is a lame approach to safety. If you make it wraparound, you now have silent wraparounds that can't be found by static analysis. You want unintended overflows to trap, not just be defined.

Re:GCC undefined behaviors are getting wild by eru on Monday November 28, 2022 @05:59AM (#33772078)
> And "defining" it is a lame approach to safety. If you make it wraparound, you now have silent wraparounds that can't be found by static analysis. You want unintended overflows to trap, not just be defined.

Yes. But even the lame approach is better than UB, because it doesn't bring the whole program down.

Re:GCC undefined behaviors are getting wild by Gibbon1 on Tuesday November 29, 2022 @04:53PM (#33793886)
I've been wondering if I should mention that using int for an index is a bad idea because the standard only guarantees it's 16 bits. You should use size_t instead. And in C size_t is unsigned.

My take is all of the low hanging fruit optimizations that the standard enables has been picked a long time ago. Everything left is problematic.

Re:GCC undefined behaviors are getting wild by eru on Monday November 28, 2022 @02:26AM (#33770670)
That's C for you. If you want something saner, use Rust or Haskell or Python or even Java or Go or.. almost any other language that's not C or C++.

These days the whole point of C is this Faustian pact with the devil of speed for sanity.

Re:GCC undefined behaviors are getting wild by consp on Monday November 28, 2022 @02:40AM (#33770776)
Writing Rust and Haskell for sanity is not something I would agree with. Maybe for language characteristics but reading those make me jump out of the window.
Re:GCC undefined behaviors are getting wild by eru on Monday November 28, 2022 @02:58AM (#33770899)
I have the same issue with Java and Go. (Which I brought up as well.)

Yet, they still compare favourably with C in this regard. Almost anything does.

Re:GCC undefined behaviors are getting wild by pca006132 on Monday November 28, 2022 @03:04AM (#33770946)
I think Rust doesn't allow integer overflow either, unless you specifically use the wrapping_* operations. Probably the same kind of thing will also happen to Rust.
Re:GCC undefined behaviors are getting wild by masklinn on Monday November 28, 2022 @03:05AM (#33770951)
Rust either allows or traps on integer overflow depending on the mode. Either way it’s defined behaviour.
Re:GCC undefined behaviors are getting wild by pca006132 on Monday November 28, 2022 @10:40AM (#33774926)
Ah, I forgot that it is also defined in release mode, but just considered undesirable.
Re:GCC undefined behaviors are getting wild by baq on Monday November 28, 2022 @02:37AM (#33770751)
And yet C is still the dominant language. Undefined behavior is actually the reason why: any defined behavior is expensive to implement in the compiler and possibly incurs a cost at runtime. The language design intentionally trades programmer’s sanity for ease of implementation.
Re:GCC undefined behaviors are getting wild by pjmlp on Monday November 28, 2022 @02:40AM (#33770774)
Legacy reasons, most embedded devs and UNIX clones won't use anything else.

In many other domains, other languages have taken their place, and this will keep on going, even if it takes a couple of generations, or goverment cybersecurity mandatates to make it happen.

Re:GCC undefined behaviors are getting wild by eru on Monday November 28, 2022 @02:50AM (#33770841)
Not sure that's actually the reason in practice?

For a real prominent counterexample: the Linux kernel is intentionally programmed in a C dialect (defined by a myriad of GCC compiler flags) that removes a lot of UB.

If they craved the Faustian bargain of UB for speed, they could immediately move in that direction by dropping some GCC options.

Re:GCC undefined behaviors are getting wild by adwn on Monday November 28, 2022 @02:54AM (#33770869)
> The language design intentionally trades programmer’s sanity for ease of implementation.

There's nothing "easy" at all about UB-exploiting performance optimizations in modern C compilers, and "ease of implementation" is absolutely not why those optimization passes have been included. In fact, the easiest thing for the compiler to do, when it sees an int * int operation, is to emit an IMUL assembly instruction (or the equivalent for your CPU architecture) and not worry about deleting overflow checking code. Which is what C compilers did before the extent of UB exploitation became excessive.

Re:GCC undefined behaviors are getting wild by baq on Monday November 28, 2022 @03:02AM (#33770936)
I agree on the top compilers but there are dozens if not hundreds architectures with their own proprietary C compilers maintained by a dinosaur and a couple intern dino chicks if they’re lucky. I postulate any other language wouldn’t be implemented or would be defanged to C-level of (non)safety anyway in a way similar to mrustc.
Re:GCC undefined behaviors are getting wild by andrewaylett on Monday November 28, 2022 @06:07AM (#33772153)
C has always considered that the programmer knows what they are doing. Programs are assumed correct unless proven invalid.

This is -- or at least was -- a feature, not a bug. You can implement any valid program, but you can also implement some invalid programs.

I know the OP mentioned Rust, but it's a valid comparison: if you don't invoke "unsafe" then all your behaviour is well-defined. But the trade-off is that Rust will only let you implement a subset of valid programs unless you invoke "unsafe", which might be better termed "assumed correct".

Re:GCC undefined behaviors are getting wild by spullara on Monday November 28, 2022 @02:49AM (#33770836)
Does the compiler know? If so, can't they have a flag that doesn't allow UB?
Re:GCC undefined behaviors are getting wild by pca006132 on Monday November 28, 2022 @03:06AM (#33770961)
Doesn't allow optimization enabled by this specific UB: Yes Does't allow UB: Hard, because you probably need runtime checks.
Re:GCC undefined behaviors are getting wild by oxff on Monday November 28, 2022 @03:05AM (#33770950)
This is a good positive model of UB, fulfilling the compiler assumptions.
Re:GCC undefined behaviors are getting wild by afiori on Monday November 28, 2022 @04:08AM (#33771318)
I don't think this is a fair comparison as this is all based on implicit inferences by the compiler.

If the programmer had specifically invoked the "__assert_valid_pointer(p)" standard function (which does not exists) to promise the compile that the pointer was valid then it would be fine.

The problem is that there are a lot of places where the compiler makes these assumptions.

Re:GCC undefined behaviors are getting wild by imtringued on Monday November 28, 2022 @09:01AM (#33773725)
"and I'm going to kill you for it even though I could also just slap you"
Re:GCC undefined behaviors are getting wild by raverbashing on Monday November 28, 2022 @02:21AM (#33770649)
Except this can't happen happens many and many times in practice so maybe it's time the language bureaucrats got off their high horse (but they won't)
Re:GCC undefined behaviors are getting wild by iforgotpassword on Monday November 28, 2022 @02:18AM (#33770623)
It's still braindead and idiotic. Every relevant platform nowadays has well defined overflow for signed ints. A sane C compiler should go with that and base its optimizations on it. GCC has been a pile of garbage in this regard for many years now. Its devs get further removed from reality with every year. Treating signed int overflow as undefined should be hidden behind a flag.
Re:GCC undefined behaviors are getting wild by masklinn on Monday November 28, 2022 @02:25AM (#33770665)
Signed int overflow being UB is one of the most basic UBs of the language, and what allows generating tight code in loops.

This is not new, -fwrapv was introduced in 2003, but it can quite severely impact code quality, if you don’t care, just set that. Then complain that C is slow, because C is a shit language.

Re:GCC undefined behaviors are getting wild by iforgotpassword on Monday November 28, 2022 @02:51AM (#33770850)
> and what allows generating tight code in loops.

How so? How does breaking an if statement the programmer added make the code faster? If they intended the check not to happen/be required, they wouldn't have written it. Let signed int overflow and leave any code that depends on its value alone. So yes maybe make fwrapv the default.

> because C is a shit language.

Well, it's as low level as it can get before reaching assembly, but why not try reducing the number of foot guns? Sometimes you still need C, and that's not going to go away for the foreseeable future.

Re:GCC undefined behaviors are getting wild by masklinn on Monday November 28, 2022 @03:12AM (#33770997)
> How does breaking an if statement the programmer added make the code faster? If they intended the check not to happen/be required, they wouldn't have written it.

See your problem is that you’re

1. not thinking like a compiler

2. and reasoning on an isolated example

The compiler does not “break an if statement”, the compiler uses the UB to limit the range of the input and output, it can then propagate this range analysis to see that the check is dead code, and so removes the dead code.

It’s common for users to write unnecessary or redundant checks, even more so because of inlining, and especially macros.

If you’re carefully checking for null in every function prologue, and the compiler in-line everything and knows the pointer is non-null, all checks are dead and can be removed. Which is what the compiler does. This reduces the amount of branches (and thus the space needed by the branch predictor), and reduces the amount of code meaning the new inlined function could fall below threshold and itself become a candidate for inlining.

Re:GCC undefined behaviors are getting wild by iforgotpassword on Monday November 28, 2022 @06:05AM (#33772139)
Ok sure, I'm using this particular example here, but I've yet to see a good counter example to convince me it's the lesser evil to let that happen.

Also I agree you should not write code like that example and rather move the check up.

But reality is we (at least I) still depend on code written in C, like openssh, and want it to be as safe as possible. Now I can blindly trust the devs know every UB in the C spec in and out, run all the static and dynamic analysis tools in existence, but it would just make me feel even more safe if the compiler would also work with them, not against. Somewhere here in the comments it was claimed that the linux kernel for example already uses -fwrapv and its performance seems absolutely fine to me. And I'd suspect that an OS kernel is already on the more performance critical end of the spectrum regarding stuff written in C that's still in use.

I just find it worrysome that such evidently unsafe optimizations are the default, and not hidden behind some sufficiently scary-sounding flag.

Re:GCC undefined behaviors are getting wild by aw1621107 on Monday November 28, 2022 @03:49AM (#33771224)
> How so?

A somewhat common example I've seen is sign extension in loops, where the width of the loop variable is not the same as that of the CPU register [0]. If the compiler can assume that signed integer overflow is UB, then it has a lot more freedom to unroll/vectorize the loop [1] (remove -fwrapv and watch Clang go to town).

Of course, that specific optimization is rendered somewhat moot if the programmer chooses to use a 64-bit loop variable, but that is a slightly different rabbit hole.

> If they intended the check not to happen/be required, they wouldn't have written it.

I feel that's somewhat iffy reasoning - if we trust the programmer so much, why allow the implementation to optimize in the first place? And if not to that extreme, where should the line be drawn?

[0]: https://gist.github.com/rygorous/e0f055bfb74e3d5f0af20690759...

[1]: https://godbolt.org/z/EMaq1j3Kc

Re:GCC undefined behaviors are getting wild by Asooka on Monday November 28, 2022 @06:00AM (#33772097)
That's one contrived example solved by changing the type of the loop variable. You have to profile your code for hot spots anyway, this loop would be immediately obvious. And if it's not a hot spot, the difference in emitted code is completely pointless.
Re:GCC undefined behaviors are getting wild by aw1621107 on Monday November 28, 2022 @12:16PM (#33776322)
I'm not sure using int as a loop variable on 64-bit platforms is that contrived. It's not like it's that hard to find examples using int these days, and I'd suspect that it is more common in older software as well.

Yes, the optimization is "easily" solved, but a) it'll probably be some time until people stop teaching/using int as a loop variable, and b) there's lots of existing software out there, and perhaps optimizer improvements are an easier performance win than looking for the right loops to change.

And yes, profiling is ideal, but I can't say whether I agree off the top of my head whether this loop would be immediately obvious, or whether the fix would be obvious. It may be to us and/or the average HN reader, but I don't know how universal that knowledge base is.

One thought that just occurred to me is that while signed overflow may be useful for loop optimizations now, I suspect that it wouldn't have been useful in the same way back when C was first standardized. Wonder what the committee's reasoning for that was, if there was any...

Re:GCC undefined behaviors are getting wild by caf on Monday November 28, 2022 @08:09PM (#33782354)
I feel that's somewhat iffy reasoning - if we trust the programmer so much, why allow the implementation to optimize in the first place?

Right. If you want each line of code to be loaded and executed precisely in sequence, exactly as written, then you know where to find Python.

Re:GCC undefined behaviors are getting wild by emn13 on Monday November 28, 2022 @02:51AM (#33770854)
The C/C++ language doesn't provide for a way for the compiler to see that you really meant this one check to take precedence over the implicit promise in another.

The reason why C++ is always relevant here (though C macros and inlining cause similar issues) is that generic programming being close to optimal is a language feature - and one of the ways that's possible is by letting you right reusable code that might be "called" from a context in which some of the checks or conditions just aren't necessary. It's by design that the optimizer gets to... well, optimize that kind of code.

There's a solid case to be made that the details of C's UB weren't well chosen and we should try to update them; but which decades old choices are perfect? Which are easy to change once there's this much legacy software in operation?

Don't forget that some of those UB's were chosen to deal with hardware realities of the day; i.e. that the "same" operation on different hardware would do different things. For example, eliminating signed integer overflow might allow a C compiler to use a signed register that's wider than necessary, which may help on hardware that doesn't have every possible register width, or where there are complex register usage limitations. I'm no hardware geek; I'm sure somebody here knows or real examples where UB allows portability, because that's the point: UB allows people to write portable, performant code - just don't do certain things, and you're fine... which leads us to today's situation, in which UB can feel like a minefield.

Re:GCC undefined behaviors are getting wild by eru on Monday November 28, 2022 @03:34AM (#33771130)
> Don't forget that some of those UB's were chosen to deal with hardware realities of the day; i.e. that the "same" operation on different hardware would do different things.

That's an argument for implementation defined behaviour. Not for undefined behaviour, at least not UB in the modern sense.

Re:GCC undefined behaviors are getting wild by emn13 on Monday November 28, 2022 @03:48AM (#33771221)
Having implementation defined behavior would imply non-portability. C compilers have all kinds of ways of exposing platform-specific features, but sneaking those into what looks like standard behavior has its own issues. And even if you accept that, that doesn't deal with the issue of inlining, generics, and macros - you can get different implementation defined behavior even in a single hardware implementation like that.

If that is what you want, compilers have various flags that let you in essence do that. But the next problem with that is (1) that it's possible existing code may be suddenly and unpredictably lose performance, and (2) now you need to provide some other well-defined behavior for those UB cases, and (3) the selling point of generics/macros/inlining may be reduced.

How many relevant UB's are there? I don't know. How much perf would code common lose? I don't know. To be sure, I fully acknowledge that removing UB from the spec may be the right thing to do, but it's also easy enough to find possible problems with that strategy; I'm just pointing out the complexities, which is a lot easier than solving them or knowing which are irrelevant.

Re:GCC undefined behaviors are getting wild by eru on Monday November 28, 2022 @04:46AM (#33771571)
> Having implementation defined behavior would imply non-portability.

Not any more than UB does. Ie if you avoid the implementation defined behaviour, your code is perfectly portable.

(And otherwise your code could probe for what the implementation defined behaviour is, and adjust accordingly. No such luck with UB.)

However I do agree with you that it's hard to remove UB from the spec. The spec's failing is in having so much UB in the first place.

Re:GCC undefined behaviors are getting wild by newaccount74 on Monday November 28, 2022 @03:48AM (#33771217)
The problem is not UB per se -- the problem is that the compiler uses UB to make assumptions that are incorrect.

Removing a comparison because of UB is fucking stupid. The compiler on the one hand assumes that the programmer is diligent enough to consider of every invocation of UB, but on the other hand too stupid to see the check they wrote will always be true.

It's not a good idea.

Re:GCC undefined behaviors are getting wild by emn13 on Monday November 28, 2022 @03:56AM (#33771262)
Checks that are always true _in some context_ are entirely normal and by design if the code can be used in a different context. If your code is reused in a way that let's the optimizer re-optimize the code per-context, then you'll benefit from the compiler's ability to remove dead code or even merely to choose less expensive special case ops. Macros, templates and inlining are some common ways that happens, but platform-specific builds and perhaps others exist too.

For example, imagine you have some SIM wide value, and you want to do something to each word or byte that the SIMD value contains. In today's C, you can just write a bunch of ifs: is width < 2? then... is width < 4? then... etc. The compiler with completely elide those ifs and leave behind only the reachable code - if it can specialize that re-used code for the given context.

Furthermore, today those checks might be implicit via the use of UB. That's perhaps not a great solution looking at the entire ecosystem, but it is the situation we're in. Changing that might be quite a lot of work.

Re:GCC undefined behaviors are getting wild by newaccount74 on Monday November 28, 2022 @06:17AM (#33772230)
I don't mind that the compiler simplifies expressions and removes code that it can prove is dead.

I just don't like that it derives preconditions from UB.

Re:GCC undefined behaviors are getting wild by gpderetta on Monday November 28, 2022 @06:35AM (#33772346)
Pretty much no property, not even the most trivial ones, of a C program can be relied upon without assuming no-UB. A compiler can't even assume that a variable won't change value between a statement to the next as it could be changed asynchronously by signal handler or thread.
Re:GCC undefined behaviors are getting wild by emn13 on Monday November 28, 2022 @11:48AM (#33775889)
Exactly - so the problem is perhaps best thought of from a different perspective - i.e. not that the compiler only considered defined behavior when rewriting code (because what else would it do?), but rather that certain behavior could have a definition, but doesn't.

It's a lot easier to reason about code for instance when the domain of signed integer addition is all pairs of integers, not just a subset thereof.

Ideally, buffer overflows would also be defined - but without lifetime analysis ala rust or runtime costs, that's going be hard. But given how many stack guarding techniques there already are, perhaps we're closer to this than I think?

Re:GCC undefined behaviors are getting wild by rocqua on Monday November 28, 2022 @04:05AM (#33771304)
I like that the compiler removes comparisons that always have the same result.

It means I can write clear code, guard things rather than explain in a comment why the guard isn't needed, and know that the compiler will remove the inefficient code. In general, optimizing compilers mean that taking the clearer option is much less of a performance loss. I like that.

In many of these UB cases, the annoying things is that the compiler removes the safety feature you explicitly added, but there are plenty of alternatives.

Re:GCC undefined behaviors are getting wild by oxff on Monday November 28, 2022 @04:11AM (#33771336)
The compiler doesn't make assumptions that are incorrect (it is what it is, basically, if it assumes no integer overflows there better not be).

Your application, and the application programmer, instead fail to fulfill those compiler assumptions.

Re:GCC undefined behaviors are getting wild by eru on Monday November 28, 2022 @02:53AM (#33770864)
It's not about what your CPU does.

These days undefined overflow for signed integers is mostly used by compilers to be able to assume that eg 'a + 1 > a' is always true, and thus eliminate redundant checks.

(And you wouldn't typically write code like 'a + 1 > a', but you can get either from code generation via macros etc or as a intermediate result from previous optimization passes.)

Re:GCC undefined behaviors are getting wild by Asooka on Monday November 28, 2022 @05:56AM (#33772052)
Basically, the compiler implements integer addition using an operation that doesn't match the semantics of integer addition in the standard, then hallucinates that it did. That is:

1) The compiler sees an expression like "a += b;" where a and b are signed integers.

2) It emits "add rA rB" in x86 assembly (rA/B being the register a/b is currently in).

3) Technically the machine code emitted does not match the semantics of the source code, since it uses wraparound addition, whereas the C standard says that for the operation to be valid, the values of a and b must be such that no overflow would occur. This is fine however, because the implementation has the freedom to do anything on integer overflow, including just punting the problem to hardware as it did in this case.

4) The compiler proceeds with the rest of the code as if the line above would never overflow. My brother in the machine spirit, you chose to translate my program to a form where integer overflow is defined.

The compiler should either a) trap on integer overflow; or b) accept integer overflow. It will be fine if it chooses either a) or b) situationally, i.e. if we have a loop where assuming no overflow is faster, then by all means - add a precondition check and crash the program if it's false, but don't just assume overflow doesn't happen when you explicitly emit code with well-defined overflow semantics.

The bigger problem is there is pretty much no way to guard against this. The moment your program is longer than one page you're screwed. You may think all your functions are fine, but then you call something from some library, the compiler does some inlining and suddenly there's an integer overflow where you didn't expect, leading to your bounds check being deleted.

Re:GCC undefined behaviors are getting wild by atoav on Monday November 28, 2022 @02:51AM (#33770844)
The hard things about C are knowing all these footguns you are getting yourself into. If our electrical grid was built like this we had no isolation, no fuses, no RCDs and a constant torrent of electrocutions and fires. It is bad engineering.
Re:GCC undefined behaviors are getting wild by fps_doug on Monday November 28, 2022 @05:04AM (#33771709)
... and people defending the status quo because "you just have to know how electricity works" :-)
Re:GCC undefined behaviors are getting wild by oxff on Monday November 28, 2022 @03:02AM (#33770941)
> On the other hand, there seem to be so many cases like this one where the “undefined behavior code deleter goes brrrrrr” really overextends its usefulness.

I would simply not depend on invoking UB as part of my program's behavior (?).

Re:GCC undefined behaviors are getting wild by eru on Monday November 28, 2022 @03:35AM (#33771143)
That's the only way to use C correctly.

Alas, it's nearly impossible to write any non-trivial C code that doesn't have UB.

Re:GCC undefined behaviors are getting wild by pjc50 on Monday November 28, 2022 @04:30AM (#33771446)
"a+b" for signed integer types potentially invokes undefined behavior (overflow). It's a horrendous situation.
Re:GCC undefined behaviors are getting wild by masklinn on Monday November 28, 2022 @03:13AM (#33771006)
Alternatively I would not trust myself with not doing that, which is why I don’t use C.
Re:GCC undefined behaviors are getting wild by vgatherps on Monday November 28, 2022 @06:20AM (#33772253)
I don't think I ever claimed that one would or should intentionally invoke UB as part of their program's behavior?
Re:GCC undefined behaviors are getting wild by lilllly on Monday November 28, 2022 @05:28AM (#33771869)
We need a -fsane-c

Then they can add a #pragma optimize(assumes=no-int-overflow, whatever, etc) to precisely add optimizations when needed and you 'know' its safe.

Re:GCC undefined behaviors are getting wild by throwaway81523 on Monday November 28, 2022 @05:31AM (#33771890)
Everyone wants that, but when asked for a concrete specification they seem to realize that it is harder than it sounds. Look for John Regehr's blog entries about "Friendly C" for an example. The basic problem here is that C is a terrible language. We shouldjust give up on it by now.
Re:GCC undefined behaviors are getting wild by sanxiyn on Monday November 28, 2022 @07:15AM (#33772674)
I provided the concrete specification. What is hard about it? Get it done already.
Re:GCC undefined behaviors are getting wild by Asooka on Monday November 28, 2022 @06:05AM (#33772135)
You can get 99% of the way there with -fno-delete-null-pointer-checks -fno-strict-aliasing -fwrapv . Pretty much every program I've worked on uses those flags, as that's the only way to keep your sanity.
Re:GCC undefined behaviors are getting wild by gpderetta on Monday November 28, 2022 @06:40AM (#33772382)
-fdwim

Next generation of AI powered compilers will try to interpret code at a more abstract level and infer what the programmer was thinking even if they wrote the wrong thing.

Everything will work perfectly 100% of the time.

Re:GCC undefined behaviors are getting wild by sanxiyn on Monday November 28, 2022 @07:12AM (#33772628)
This already exists. Don't write standard C, avoid it like the plague. Compile with -fno-strict-overflow -fno-strict-aliasing -fno-delete-null-pointer-checks, like I do, like Linux kernel does, and like everyone sane does.
Re:GCC undefined behaviors are getting wild by NohatCoder on Monday November 28, 2022 @08:03AM (#33773102)
No, not everyone sane. Rather everyone sane who has been bitten enough by these issues to use such rules. Everyone starts out at -O2, because understanding all the other flags and their implications is super difficult. As long as the insane setting is default, a large percentage of programmers will be using the insane setting. Arguing that they should have flagged their compilations otherwise is about as useful as pointing out that people shouldn't write UB in the first place.
Re:GCC undefined behaviors are getting wild by sanxiyn on Monday November 28, 2022 @08:17AM (#33773251)
Sure, I 100% support changing the C standard. Until it is done, compiling with flags is infinitely easier than trying to avoid these UBs.