4 ms·
It's perfectly reasonable to argue that C is not as good as XYZ. You may even be right. But it is not reasonable to conclude from that, that it ok for C impleme
by vyodaiken 8y ago
It's perfectly reasonable to argue that C is not as good as XYZ. You may even be right. But it is not reasonable to conclude from that, that it ok for C implementations to make C programming more hazardous than it needs to be. Go out and make Rust a more appealing alternative to C and good luck with it. But don't tell me C can be turned into mush because you don't much like C.
- pjmlp 8y agoRest assured, it is quite clear to us that until we get rid of UNIX clones, C isn't going anywhere. So the only alternative is to improve the band-aids and keep sponsoring PhDs on security research related to C.
- geofft 8y agoDon't get me wrong, I like C. I don't want to write production software in C any more, but I do actually like the language a lot. Le cœur a ses raisons. C is already mush. Maybe it wasn't in the 1980s, but it certainly has been since I first started learning C (around 2000). I'm simply responding out of rational self-interest to recognizing that C cannot be what I want it to be, and what I want it to be looks an awful lot like Rust (or Go, or Swift, or...). C doesn't even have sum types with a language construct for exhaustive matching. That, by itself, makes C programming dangerous. For every NULL check unexpectedly deleted by a compiler, there are a thousand NULL checks that weren't written in the first place, because C has no mechanism to require a NULL check before using a pointer.
- keldaris 8y agoIt is perfectly ok for C implementations to make C programming as "hazardous" as they want to. It's up to you whether you want to use them. Frankly, I don't understand the UB hate at all. There is a rapidly growing space of programming languages specifically designed to give you safety guarantees and well defined behavior. If that's what you want, by all means use them. There are still those of us out there for whom even `-fwrapv` represents an unacceptable loss in performance for certain programs. There is an important and valuable niche for a language that enables compilers to optimize code without regard for saving programmers from mistakes in their code, and that's always going to be the case. Most people probably shouldn't be using it very much, but that's an entirely different issue from trying to "fix" what's not broken in C.
- vyodaiken 8y agoI'd love to see some examples of how -fwrapv makes real programs see an "unacceptable loss in performance". Are there any? I confess to doubt.
- keldaris 8y agoThat's easy, I'm working on a computational kernel (for a scientific simulation of fluid dynamics) right now that loses ~20% performance the second you compile it with -fwrapv in GCC (the corresponding factor is slightly smaller in clang, because it's worse at optimizing it in the first place). I haven't invested enough effort in it yet to tell you if I could beat the compiler with manual optimizations in a sane amount of time, but the difference is certainly pronounced. I haven't stumbled across anything new or unique here, it's just that most people don't write compute-constrained kernels that often these days. The optimization benefits of UB for signed integers are well known, and that's just one useful example of UB in C compilers. And again, I'm fully on board with the notion that many people would be better off with a more error tolerant subset of what C does - and there's a lot of languages that provide just that. I'm just saying there are real costs to the change and they matter.
- vyodaiken 8y agoI love to see code snippets. Otherwise this makes zero sense. The check for overflow is super cheap on any processor you'd run fluid dynamics code on. You'd have to be running pathologically tiny loops. I have never seen any papers on this "well known" benefit. Perhaps you can provide me a link. In any event, it's interesting that you think that compute intensive kernels are self-evidently more important uses of C than device drivers, embedded systems, middleware, etc. Perhaps you'd be better off using a language specifically designed for optimized numerical codes - FORTRAN for example.
- keldaris 8y agoI can't release the whole codebase before publication, but if you're really serious about analyzing it, I can probably sanitize it in an evening and get you an MWE. Regardless, apart from pathological integer math cases, these things have little to do with the cost of overflow checks. Rather, it's about the followup optimizations the compiler can do after the UB frees it from a restrictive assumption. The trivial common examples (optimizing x*2/2 to x for integers, etc.) don't really capture the impact of these things very well, because you can't demonstrate it in a oneliner, but you can derive representative examples pretty easily if you take tight-ish loops (>16 independent loads, some SIMD-able compute, a few dependent stores at the end) and switch the index types. The vectorizer is often easy to defeat if it can't assume no overflows, the cost of the check itself is irrelevant. On your last point, I don't think compute intensive kernels are "self-evidently more important" than anything else. I think there are usecases - like scientific computing, device drivers and embedded software, to name a few - that often benefit from prioritizing programmer control over any safety net, and FORTRAN doesn't cut it for many of those uses. There are plenty of languages that give you all the safety you could possibly want. C/C++ have never been about that and I don't see why that should change. Use the right tool for the job, by all means advocate for people who don't need this level of control to use something "safer", but the notion that every tool should be blunted to some common denominator just makes no sense to me.