(Replying to PARENT post)

IMO, it's a little subtler than that. It's not the compiler's fault, it's the language's. Plenty of languages have no undefined behavior that can be written by accident. Go and safe Rust, for instance, have just about no undefined behavior at all, and are both performance-competitive with C. (Go has UB if you cause race conditions, and Rust has UB within `unsafe` blocks analogous to C's UB.)

A C compiler, meanwhile, has to aggressively take advantage of undefined behavior to get good performance, and the C specification has been keeping behavior undefined for the benefit of compilers.

You can hope that you find all such problems in C (which you might not) and "fix the program", but you can also "fix the program" by switching to a better language.

๐Ÿ‘คgeofft๐Ÿ•‘10y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

Yes, the C language specification is a bit shit, it leaves too much leeway to compilers so that C compiler for broken, niche architectures can be written. However, I disagree with you. All this badness in the C specification did not stop people from writing reasonable C compilers for reasonable architectures for decades.

The real problem here is competition. Gcc is in a competition with clang to produce fast code which makes the gcc developers feel justified when they exploit undefined behaviours for marginal optimizations.

This is a case of following the letter of the law (in this case the C standard) while disregarding its spirit: all the undefined behaviour was so that C compilers could accomodate for odd architectures while remaining close to the metal, not so that compiler programmers could go out of their way to turn their compiler into a mine field.

๐Ÿ‘คEdiX๐Ÿ•‘10y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

I don't think it's the language's fault either: C is four decades old, and being bound by reverse-compatibility, they can't integrate much of the programming language research that has happened in the last four decades. I'm a less concerned with placing fault for the problem than I am with placing the responsibility for fixing the problem, and that's clearly on the writer of the program which uses undefined behavior.

I think choosing Rust might be a reasonable way to avoid the problem in the first place, so I agree with you there, but there are also reasons to choose C over Rust. Personally, I write a lot of C code because I prefer to build on a GPL stack. This is one of the reasons I'd like to see Rust added as a GCC language. Sadly I don't have the time to do it myself.

๐Ÿ‘คcopsarebastards๐Ÿ•‘10y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

Umm wait. Undefined behavior is where the language specification is not 100% precise, and compiler implementations can differ on produced code.

Go and Rust only have single implementations. The specification for both are very brief. Are you claiming that a clean box implementation of Go and Rust would always behave identically?

I have only one thing to say: I clicked through the Golang spec for 30 seconds and found this: https://golang.org/ref/spec#Run_time_panics

> The exact error values that represent distinct run-time error conditions are unspecified.

Oh, what's that? Undefined behavior? In the golang spec?!

๐Ÿ‘คRyanZAG๐Ÿ•‘10y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

This makes it sound like Go and Rust have some secret sauce that enables C's performance without UB. But it is not so.

For example, consider an expression like (x*2)/2. clang and gcc will both optimize this to just x, but Go and Rust will actually perform the multiplication and division, as required by their overflow semantics. So the performance vs safety tradeoff is real.

๐Ÿ‘คridiculous_fish๐Ÿ•‘10y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

You can't compare traditional GC languages like "Go" to C. They inhabit two different universes.
๐Ÿ‘คGPGPU๐Ÿ•‘10y๐Ÿ”ผ0๐Ÿ—จ๏ธ0