← Back to context

Comment by josephcsible

3 years ago

If this kind of optimization is unacceptably risky for your use case, you need a different programming language, not a different C compiler.

"unacceptably risky" except I can't think of anything more basic than asking the computer if a > b and it fails at that?

  • UB invades your whole program, not specific lines.

    However in this case, the culprit wasn't comparison `a > b`, but assignment `a = b`.

    In general, addition like 'a + b' also isn't safe in C.

    • It's not the assignment. It's the multiplication x * 0x1ff.

      The compiler has done range analysis and knows that at this point, x is non-negative. The programmer has dilgently ensured that values are such that the multiplication can't overflow, therefore the result of it is also non-negative. That means the later check for i being non-negative is trivially true.

    • If it's wrong break on compiler time, not on run time

      The problem is the compiler going implementation defined on the multiplication/assignment then going all language lawyer on the following line and blaming the user

      > In general, addition like 'a + b' also isn't safe in C.

      Cool, another reason to retire it

      5 replies →

  • how does it fail at that? it does exactly what the standard advertises. you need to write standard-compliant code.

It would seem GCC is doing its very best to make C an irrelevant language. They're taking "-pedantic" a bit too seriously.

  • All optimizing compilers do stuff like this. You yourself ask the compiler to do it when you pass it '-O2'. Its default behavior is, in fact, to not optimize based on the assumption that UB won't happen.

Do you have any specific languages in mind?

  • Author of linked article mentions Rust

    • Fun thing there is rust feeds into the same optimisation pipeline as C or C++, so there's a definite risk of it inheriting some of their semantics via errors in the compiler implementation.

      4 replies →

    • Rust is a good replacement for most use cases, but I think specifically in case where you're looking for a more predictable and less risky implicit behavior, the replacement should be more stable and predictable than Rust is at the moment.

      2 replies →

  • Basically anything else.

    • C has a specification and weird stuff doesn't happen as long as you follow it. Doing so is very hard at times, but if a project cares about unpredictable optimizations, then it probably also cares about other kinds of unpredictable behavior. Which unfortunately eliminates a lot of languages that make no guarantees about their semantics.