Live data from Hacker News

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

metzdowd.com

71–80 of 110 posts

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

#71
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?

Any time you add two (signed) integers, that's potentially undefined behaviour.

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

#72
post #45

Earlier quoted context omitted.

The problem is that it's often perfectly clear, reasonable code on all the systems it was intended to run on. For example, on all Unix-like systems, pointer arithmetic is simply arithmetic and behaves like it. (C's predecessor didn't even have separate pointer and integer types.) So prior to compiler optimisations, this series of operations is safe and well-behaved on all architectures Linux supports even if a is NUL…

I understand the problem, I'm saying that it's not GCC's problem. If you don't want undefined behavior, don't put undefined behavior in your code. The code you wrote isn't clear or reasonable, because it relies undefined behavior. It's a valid criticism that this code does appear to be straightforward when it isn't, but that's not a criticism of GCC, it's a criticism of ANSI C. If you don't like it, use a better lang…

ANSI C didn't really do anything wrong here, though - they created a least-common-denominator spec of what you could reasonably expect from C across all platforms. Pointer arithmetic on NULL pointers had to be considered undefined (not just unspecified) in ANSI C, because on certain commercially-important proprietary systems it generated a hardware trap that caused the OS to kill your process. The problem is that the gcc developers insisted on actually making that code behave as undefined even though it didn't make sense to.

Also, I should note that a lot of code - particularly the Linux kernel - isn't actually using ANSI C anyway. They're using a superset of it with gcc extensions and they have a whole bunch of architecture-specific code too.

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

#73
post #66

Earlier quoted context omitted.

> 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. Computers don't have spirits; they work as you tell them to work, to the letter…

>Computers don't have spirits But standards committee do. >Rust is extremely impressive because they've found so many ways to do high-level programming while maintaining low-level performance. But they can only do that because they have the benefit of the 4 decades of programming language research that have occurred since the basics of C were designed. I doubt rust could be ported to a 8bit PIC microcontroller, or to…

>> Computers don't have spirits

> But standards committee do.

Agreed. Which is why you should choose a language which was standardized by a standards committee whose goals better align with your goals.

> I doubt rust could be ported to a 8bit PIC microcontroller, or to a 6502 keeping reasonable performance characteristics or letting the programmer take advantage of the platform quirks.

I don't think that's true; I think that the current state of Rust tools is such that this is true now, but it's nothing inherent to the design of the language, and I think you'll be able to do quite a bit with Rust in the situations you describe when the tools around Rust are more mature. I can't really speak to this more because I'm not sure why you think this can't be done.

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

#74
post #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…

Even C compiler developers can't always get it right. There have been a few bugs where, for example, one compiler pass optimised a struct initialisation into a single write that wrote into the slack space after the end of the struct, and a subsequent pass detected this undefined behaviour and removed the initialisation altogether. (These optimisation tricks inherently make compiler development more risky, because they mean that composing safe compiler passes is likely to create something unsafe.)

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

#75

Earlier quoted context omitted.

Yeah, I'd go so far as to argue that if you need security, you probably shouldn't be writing C.

What you and a lot of other people are missing, cheerful in your use of other languages, is that your runtimes and native extensions usually depend on insecure C code .

I'm not missing that; you're making an assumption.

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

#76
post #32

Earlier quoted context omitted.

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).

You could always write one. I recommend the work of John Regehr as a starting reference: http://blog.regehr.org/

I wish I had time to learn this first :)

But yes, authoring a book titled "Well-defined C (and C++)" one day would be awesome.

Thanks for the link.

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

#77
post #69

Earlier quoted context omitted.

> On two occasions I have been asked, — "Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?" In one case a member of the Upper, and in the other a member of the Lower, House put this question. I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question. --Charles Babbage The modern version of this seems to be: "Mr. Babbage, I put the…

I'm reminded of http://mjg59.livejournal.com/108257.html : "POSIX says this is fine, so any application that expected this behaviour is already broken by definition. But this is rules lawyering. POSIX says that many things that are not useful are fine, but doesn't exist for the pleasure of sadistic OS implementors. POSIX exists to allow application writers to write useful applications. If you interpret POSIX in such…

And it does that by implementing a compiler for a language with existing standard, which is ANSI. If you don't like the ANSI C standard (and I admit it's not perfect), don't use a compiler for ANSI C.

Also, this is not just GCC problem, all the existing C compilers have the issue to some extent. After all, STACK (the MIT tool to detect undefined behavior) is based on clang. And ICC exploits the same UB tricks AFAIK.

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

#78

Inknow people are quick to complain about programmers relying on UB here but this really is a long standing disagreement with the gcc folk. They are language lawyers of the worst sort and do not consider security implications being a point of discussion :(

> On two occasions I have been asked, — "Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?" In one case a member of the Upper, and in the other a member of the Lower, House put this question. I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question. --Charles Babbage The modern version of this seems to be: "Mr. Babbage, I put the…

I absolutely agree with this. GCC implements ANSI C, and that unfortunately includes undefined behavior for various reasons. The problem with undefined behavior is that it's, well, undefined. Different compilers might choose different things, because different developers have different mental models of "what makes sense" in various situations. Which is hardly an improvement. Also, it wouldn't be ANSI C but some unknown mutation of C.

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

#79
post #50
post #23

Earlier quoted context omitted.

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

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

Yes. The worst part of it is that compilers have the option to do something sensible when handling undefined behaviour. The standard even suggests doing that, describing one possible option as behaving "in a documented manner characteristic of the environment". So why doesn't gcc do that?

People are far too keen to assume that because the standard leaves it undefined, and "undefined" sounds a bit here-be-dragons, it's therefore inevitable that undefined behaviour has to be some nasty creepy ugly thing. That it renders your entire program instantly meaningless. That it's a perfect excuse for the compiler to look at your program and turn it into something completely different. But... it doesn't have to be.

I don't know why people don't treat handling of undefined behaviour as a quality of implementation issue, rather than just rolling over and letting gcc make their lives worse.

Mandatory links: http://blog.metaobject.com/2014/04/cc-osmartass.html, http://robertoconcerto.blogspot.co.uk/2010/10/strict-aliasin...

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

#80
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…

Who is at fault in your example becomes much less clear cut when you consider the variant where the author of foo doesn't have access to the source code of bar and baz and they only rely on shared state on some systems or in some corner cases.
Post reply on HN