10 ms·
“Safe C++ Subset” Is Vapourware
- catnaroek 10y agoAgreed wholeheartedly. Take this blog post, replace “Lisp” with “C++”, “Haskell” with “Rust”, and “type system” with “lifetime system”: http://axisofeval.blogspot.com/2011/01/why-lisp-is-big-hack-and-haskell-is.html http://axisofeval.blogspot.com/2011/01/why-lisp-is-big-hack-.... “C++, as it stands, can't do any of that, and won't be able to do any of that. That's simply a fact. Why? Because it's coming at the problem from the wrong direction. Trying to graft an interesting lifetime system or verification onto C++ is simply too heroic and ill-specified a task. C++ starts with ultimate freedom/unsafety, and you can't constrain it. Rust starts with ultimate bondage/safety, and then, piece by piece, adds that freedom back. On a theoretically well-founded basis.” This summarizes C++'s safety woes.
- junke 10y agoThe article you link starts with: > 2013 Update: I was young and stupid when I wrote this.
- tome 10y agoBut sadly doesn't explain any further ...
- catnaroek 10y agoWhich doesn't detract from the fact that it's easier to carefully add freedoms to a safe language, than it is to constrain an unsafe language until it becomes safe.
- coldtea 10y agoYes, but while easier it is also less useful -- since the unsafe language we're talking about has millions of users, billions of lines of codes, tons of libraries, huge support, hundreds of books, great tools, etc. The safe one, not so much. So making the unsafe language safer (even if not completely) can have much bigger impact and to far more people than touting some perfectly safe little language.
- catnaroek 10y ago> Yes, but while easier it is also less useful -- since the unsafe language we're talking about has millions of users, billions of lines of codes, tons of libraries, huge support, hundreds of books, great tools, etc. The safe one, not so much. Is this a plea for sticking to broken technologies 'cause social/environmental reasons?
- junke 10y agoI am not trying to refute your point. You selectively quoted a part of an article without acknowledging that the original author changed his mind later, which I found misleading. This is unrelated to C++/safety.
- lmm 10y agoI don't think there's anything wrong with that. Either the article has valid arguments or it doesn't - whether the author agrees with it today or not.
- junke 10y agoIt is true that arguments don't change and should be examined from their own qualities, but people are generally irrational and attach importance, implicitly, to meta-data. If I am an author and I put a note saying "this is not my point of view anymore", and you cherry-pick a quote like nothing changed, this is misleading because, willingly or not, this is an appeal to authority. Just as if someone was on your side saying "I approve what you say". The subtext is different if that person actually says "I once thought the same thing as you, but this was wrong and naive". I would expect a simple "take this blog post (note: author changed his mind since then) and replace...". Or maybe just write down your own version of the argument, with your own words.
- lmm 10y ago> this is misleading because, willingly or not, this is an appeal to authority. Interesting. To my mind it's the appeal to what the author thinks today that's the appeal to authority, because there's no explanation given for that, whereas the argument as written stands on its merits as an argument.
- Animats 10y agoI tend to agree. Fixing C++ memory safety without turning it into a different language is hopeless. It's been tried many times. I took a crack at it once. So did the Rust designers. There's a whole literature on this. You have to forbid too much. Previous attempts include Microsoft source code annotation language (SAL), Cyclone (AT&T research language), SCC, the Safe C compiler, Ccured, and MemSafe. None really went anywhere. What this probably means is another sort-of-safe dialect of C++, accompanied by hand-waving and PR. C++ is trying to do single owner semantics, but without something like Rust's borrow checker, the best you can do is crash at runtime on violations of move semantics. You have to design the language around borrow checking to get ownership right. Still, it's good that the C++ crowd is trying. A decade ago, I was trying to get the standards committee interested in memory safety issues, but they were into exciting new template features used by few.
- lloeki 10y agoYou can add to this list strictly-restricted subsets of C++ used for kernel development because it just has to be sane. A notable example is Darwin and kexts. I don't know what the NT folks are using.
- catnaroek 10y agoThe idea that you can find a sane subset of C++ is itself insane.
- nickpsecurity 10y agoReally? https://news.ycombinator.com/item?id=11895686 https://news.ycombinator.com/item?id=11895686
- catnaroek 10y agoFrom your linked post: > https://www.cis.upenn.edu/~eir/papers/2013/ironclad/paper.pdf https://www.cis.upenn.edu/~eir/papers/2013/ironclad/paper.pd... It still relies on dynamic checks. So you still have the same problem as in Java: just because you have a reference, it doesn't mean you actually have a valid object. You can make any language trivially safe by checking absolutely everything at runtime, but the whole point to using a language like C++ is to not incur in unnecessary performance overheads. > http://research.microsoft.com/en-us/um/people/marron/selectpubs/Undangle.pdf http://research.microsoft.com/en-us/um/people/marron/selectp... Have you actually read the paper? This isn't a static analysis at all. It just makes a dynamic analysis more eager and precise.
- pjmlp 10y agoYes, Core C++ will never make C++ as safe as Rust. However a programming language is just so much more than the language itself. So until Rust can make up for the libraries, IDE integration, GUI libraries, ability to use COM and WinRT as if they C++ classes (C++/CX, C++ Builder, Delphi), mixed mode debugging like C++ has with JVM and .NET IDEs... Many of us that need to stay in C++ land would rather have a bit of Rust security around our tools, than having to leave all that behind while Rust libraries continue to make use of Rust nightly just to get that tiny cool feature X. If this isn't the case, it is how it looks form HN posts. Last case being one doing so for the Regexp macros, I just forgot the name. I know how hard this is, after all I am part of C++ community since the C++ ARM was the only language standard available and used to be part of Turbo Pascal, Modula-2 and Oberon communities. However, at least the C++ community is trying to make the language safer even if due to Rust's pressure. Not like the C community that the best they have came up with was the optional Annex K (Bounds-checking interfaces), which doesn't offer any value. Pointers and lengths are still used separately anyway.
- achamayou 10y agoThe C community has things like Frama-C and CompCert, because they're not pursuing exponential complexity in their language. As you correctly point out at first, the value of a language is more than the language itself, it's also the tooling and the environment. And since you can't retrofit safety in the language, it's a good place to work on it.
- Thiez 10y ago> The C community has things like Frama-C and CompCert, because they're not pursuing exponential complexity in their language. Could you elaborate on what complexity you are referring to, and what makes it exponential?
- catnaroek 10y agoStatic analysis tools for C suffer from modularity issues: These tools are primarily based on abstract interpretation, so their results are very sensible to the control flow of your program. This means that your procedures, as analyzed by these tools, are connected by monstrous preconditions and invariants that describe the state of your program in each control flow path the program could possibly take. For obvious reasons, this doesn't scale.
- makecheck 10y agoI’ve found that binding C++ to a scripting language makes a lot of sense when dealing with safety issues (and other problems). While I have worked on plenty of C++ projects that had sections with performance-critical code or frequently-allocated data structures that need careful control over memory, I have never seen an entire program in this category. For that matter, I probably haven’t seen one with more than 40-50% of the C++ code in this category. Invariably, you start to see people write painful code to do trivial-things-that-are-not-trivial-in-C++, intermixed with the things that might actually benefit from C++. You can offload a lot of less-critical C++ code, forcing it into a higher-level programming environment where fewer things can go wrong, in a language that is accessible to more programmers.
- catnaroek 10y agoOne big problem with most high-level languages is that their support for automatic resource reclamation is limited to garbage collection, which is grossly inadequate for non-memory resources.
- mingodad 10y agoI did a fork of Squirrel -> SquiLu https://github.com/mingodad/squilu https://github.com/mingodad/squilu because I found the syntax more familiar and also been made with C++ that make create extensions easier than plain C. Then I started adding more and more C/C++ like syntax options with the idea to have a way to develop fast prototypes in a way that could be migrated to C/C++ when performance was not good enough, the idea is to be able to parse and accept C/C++ syntax but without actually inforce it at scripting level (accept discard/warning) and be able to use a real C++ compiler to do the heavy work. Ideally it'll lead to something like Terra http://terralang.org/ http://terralang.org/ or Cxx.jl https://github.com/Keno/CXX.jl https://github.com/Keno/CXX.jl But now Haxe http://haxe.org/ http://haxe.org/ has several advantages that's worth consider.
- pjmlp 10y agoThose languages provide other mechanisms, but people keep ignoring them on this discussions. Besides the usual set of using, with, try-finally, there are higher order functions for those languages that support it. For example, with-file "/pathname" { //fd is only visible and open here } accept-connection { // socket } // .... You just need higher order functions and implicit parameters to be able to do that in your GC language of choice.
- 2bitencryption 10y agoThe other day I thought "I'm finally gonna dive deep into C++, and I'm going to start out right, with a mindset toward modern C++ and statically forbidding memory errors, etc." First thing I did was write up a test program that looks something like this, to see what errors I would get: int x = 42; int* px = &x; px++; *px = 12; Compiled on GCC with -Wall. No warnings. I thought for sure some warning must prevent pointer arithmetic. After asking around I guess what I did above wasn't really pointer arithmetic, at least not in the compiler's eyes, so it's not warned against.
- mfukar 10y agoSo you are disappointed some random language isn't more like what you imagined. Great. Here's to hoping you don't go about your day with the same attitude.
- 2bitencryption 10y agoheh not really. more like "I'm disappointed that gcc/clang doesn't even give me the option to warn me from doing something that I will surely never want to do, even if it is "legal" (but undefined) C++, for the sake of safety."
- voyou 10y agoPointer arithmetic isn't "something that I will surely never want to do"; it's something you want to do all the time in C (and therefore in C++ written in a more C-like style). Illegitimate uses of pointer arithmetic, such as your example, are only easy to detect in trivial cases like yours. I assume this is why no one has bothered implementing a warning for this special case. In C++, directly using pointers to access arrays is often discouraged, in favour of using the standard collection types and their associated iterator types. So in code that follows this style, it is possible to warn about uses of pointer arithmetic, and the core C++ guidelines do suggest such a warning. But the guidelines also point out that "this rule would generate a huge number of false positives if applied to an older code base": https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#r2-in-interfaces-use-raw-pointers-to-denote-individual-objects-only https://github.com/isocpp/CppCoreGuidelines/blob/master/CppC...
- cLeEOGPw 10y agoI would question if 100% memory safety is a goal worth achieving in itself. Everything comes with a price. At some point, making memory management more safe starts to come with some trade offs, performance, code flexibility and others. Sometimes "good enough" is actually good enough. Why C++ will probably not be changed by other languages is the freedom it provides. It is a language equivalent of giving you absolute power of everything, including digging a massive hole, falling into it and not being able to crawl back out. Yes, Rust is safer in and of itself, and "encourages" safety, but it is also like riding a bike with a safety wheels and cushions strapped everywhere. At some point it will start just getting in your way more than helping you. In the end it boils down to purity and elegance vs. efficiency and practicality. And I'm bigger fan of efficiency and practicality than purity and elegance.
- dikaiosune 10y ago> At some point it will start just getting in your way more than helping you. This doesn't match my experience using Rust, and I've in fact found quite the opposite.
- xg15 10y agoThose are some nice metaphors, but what would a concrete example be, where you absolutely need unsafe memory operations to archieve certain performance levels? ("Need" meaning "it's fundamentally impossible to do it safely", not just "the language provides no way to do this")
- comex 10y agoThere is no such thing as "fundamentally impossible to do it safely": if you use a theorem prover like Coq then you can formally verify any* code as correct, not just memory safe but truly bug free. See seL4. You'll have to write like 20 lines of proof code for every line of real code, and that code is difficult to write... but it's possible. On the other end of the scale, Rust doesn't have much annotation overhead, but if you truly want zero cost, the borrow checker has significant limitations - you can't have any cycles in your ownership graph, not even parent pointers. The alternative is to live with reference counting overhead, and I'm not sure how much benchmarking has been done of exactly how much overhead that is, but the community tends to value pragmatism over purity, so a lot of data structure libraries take the third option and use `unsafe` fairly liberally behind the scenes. (Which makes the parent's point somewhat inaccurate - Rust is not pure 100% memory safety; unfastening the seatbelt is possible. You just have to explicitly request it.) Of course, there is a huge gulf between those two paradigms. There are languages out there that could be said to live somewhere in the middle, like ATS, but they're not popular, and in general I think the spectrum is quite poorly explored. Certainly in theory there should be a fair amount of room to build from Rust's pragmatic approach and improve on it, by expanding what kinds of ownership models can be checked and/or reducing annotation overhead - but so far nobody has figured out what such an improvement could actually look like (except maybe this C++ thing, if it's not vaporware, heh), so it's up in the air how far this can be taken. I expect and hope Rust itself will continue to improve. * Technically not any, due to Gödel's incompleteness theorem, but certainly any code a human would write. (Anyone who cites either the incompleteness theorem or the halting problem as having practical relevance to basically anything in computing is mistaken.)
- saynsedit 10y agoRust is better than C++
- nickpsecurity 10y agoIt's not vapourware: it's called Ironclad C++ and it's on Github. :) https://www.cis.upenn.edu/~eir/papers/2013/ironclad/paper.pdf https://www.cis.upenn.edu/~eir/papers/2013/ironclad/paper.pd... https://github.com/crdelozier/ironclad/ https://github.com/crdelozier/ironclad/ Rust still wins out against it. Yet, a C++ subset with type and memory safety capabilities does exist. The benchmarks look good with conservative GC and all checks on. I vote it as worth consideration for anyone trying to improve C++ app's safety. Might be worth FOSS types improving on if they're sticking with C++. Edit: Removed link to tool tgat wasnt static. My mistake on that.