Live data from Hacker News

“gcc will quietly break nearly half of all the packages that it compiles”

metzdowd.com

31–40 of 110 posts

Re: “gcc will quietly break nearly half of all the packages that it compiles”

#31
post #11

Earlier quoted context omitted.

Actually it's still a useful question, I think. A simple example is function argument evaluation order. If you have: foo(bar(), baz()) A compiler is free to call these functions in either order. That means if baz relies on state mutated by bar, the program may behave differently if the compiler chooses to reorder evaluation.

There's a parable where a man goes to the doctor and says, "Doctor, whenever I drink my coffee with the spoon in the cup, the spoon handle pokes me in the eye and it hurts." And the doctor says, "Well, stop doing that." If you wrote `foo(bar(), baz())` and `baz()` relies on state mutated by `bar()`, your code is bad, and you should feel bad, because experiencing those bad feelings is the way you learn to not write ba…

Uhh... The question was "what's an example of undefined behaviour". I gave one, specifically of an example that could realistically break by relying on undefined behaviour.

That's it. Simple education.

In the context of this post I think that's a good thing because not everyone will understand the topic.

You, however, seen to have read some sort of agenda in the question, which I find a little baffling...

Re: “gcc will quietly break nearly half of all the packages that it compiles”

#32
post #11

Earlier quoted context omitted.

Actually it's still a useful question, I think. A simple example is function argument evaluation order. If you have: foo(bar(), baz()) A compiler is free to call these functions in either order. That means if baz relies on state mutated by bar, the program may behave differently if the compiler chooses to reorder evaluation.

That is called unspecified behavior not undefined behavior. Major difference.

Not many know (and less people care), funnily :)

I have yet to see a thorough (source-to-compiler-intent-to-assembly) comparative description of undefined, unspecified and implementation-defined behaviors, though (not just a somewhat insightful blog, or techno gospel, which the C and C++ standards are).

Re: “gcc will quietly break nearly half of all the packages that it compiles”

#33
post #2

Headline is misleading. What's going on here is that the GCC developers feel free to change the generated code for behaviour undefined in the C spec. This means they might alter the behaviour of code since 40% of all packages in Debian (the "half of all packages" mentioned here) contain code whose behaviour is undefined. But the poster seems to define any change in behaviour as "breaking" code, which is ridiculous. H…

Nasal demons.

Re: “gcc will quietly break nearly half of all the packages that it compiles”

#34
post #8

Since compilers (and by "compilers" I mean gcc mostly) quietly break your code behind your back, you have no way of telling whether you really fixed things or not. Compile your test suite with -fsanitize=undefined.

That will catch a tiny part of undefined behavior.

Why doesn't the compiler emit a warning for all UB it finds while compiling? Or do regular programs rely on this too much to be feasible? It must be something like that, or there'd not be much performance gains to be had by exploiting UB right?

Re: “gcc will quietly break nearly half of all the packages that it compiles”

#35
post #26

Earlier quoted context omitted.

Yes, the pointer comparison is UB but if the compiler didn't go out of its way to screw you over UB code then it would be a reasonable way to prevent deadlock.

There is a defined method for comparing such pointers. Take unsigned char pointers to them and inspect their bytes. Then write your code, using that information, that does the comparison, assuming you know your architecture. It is defined behavior to read the bytes of any object using unsigned char.

Alternatively, if the implementation supports uintptr_t, you can convert to that and then compare the respective integral values.

Re: “gcc will quietly break nearly half of all the packages that it compiles”

#36
post #8

Earlier quoted context omitted.

That will catch a tiny part of undefined behavior.

Why doesn't the compiler emit a warning for all UB it finds while compiling? Or do regular programs rely on this too much to be feasible? It must be something like that, or there'd not be much performance gains to be had by exploiting UB right?

It's not necessarily detectable statically.

Re: “gcc will quietly break nearly half of all the packages that it compiles”

#37
post #23

The only reasonable thing to say about this was already said upthread of the page, and quoted here: > I have worked on many programs, and whenever I found such a problem (typically called a "portability problem"), where the code was assuming something that the language did not guarantee, I fixed the program rather than bitching about the compiler.

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

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?!

Re: “gcc will quietly break nearly half of all the packages that it compiles”

#38
post #23

The only reasonable thing to say about this was already said upthread of the page, and quoted here: > I have worked on many programs, and whenever I found such a problem (typically called a "portability problem"), where the code was assuming something that the language did not guarantee, I fixed the program rather than bitching about the compiler.

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

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.

Re: “gcc will quietly break nearly half of all the packages that it compiles”

#39
post #31

Earlier quoted context omitted.

There's a parable where a man goes to the doctor and says, "Doctor, whenever I drink my coffee with the spoon in the cup, the spoon handle pokes me in the eye and it hurts." And the doctor says, "Well, stop doing that." If you wrote `foo(bar(), baz())` and `baz()` relies on state mutated by `bar()`, your code is bad, and you should feel bad, because experiencing those bad feelings is the way you learn to not write ba…

Uhh... The question was "what's an example of undefined behaviour". I gave one, specifically of an example that could realistically break by relying on undefined behaviour. That's it. Simple education. In the context of this post I think that's a good thing because not everyone will understand the topic. You, however, seen to have read some sort of agenda in the question, which I find a little baffling...

You're right; I'm sorry for misreading your intention. I've edited my post so it's not as directed at you.

Re: “gcc will quietly break nearly half of all the packages that it compiles”

#40
post #2

Headline is misleading. What's going on here is that the GCC developers feel free to change the generated code for behaviour undefined in the C spec. This means they might alter the behaviour of code since 40% of all packages in Debian (the "half of all packages" mentioned here) contain code whose behaviour is undefined. But the poster seems to define any change in behaviour as "breaking" code, which is ridiculous. H…

The real problem is any software that truly relies on undefined behaviour for correct operation (which, I'll bet, is far less than the 40% cited here).

I'd bet it's well into double digits relying on undefined behaviour, and over 50% relying on unspecified behaviour. It's hard to write interesting code in C that doesn't, where interesting means code that couldn't just as profitably be written in a different language with stronger memory safety.

Programmers have a mental model of many things - in particular, 2's complement signed numbers, and the idea that pointers are just numbers indexing memory - that are not guaranteed by the C spec. Much of the reason for programming in a lower level language is to take advantage of lower level machine characteristics, like tagged pointers, unsafe unions, structs with blobs of data appended to avoid an indirection, custom memory allocators, etc., but the C abstract machine doesn't necessarily give all the guarantees required, without a lot of care and attention to details.

Post reply on HN