
“Safe C++ Subset” Is Vapourware - ndesaulniers
http://robert.ocallahan.org/2016/06/safe-c-subset-is-vapourware.html
======
pjmlp
Yes, 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.

~~~
jfoutz
You are right. rust is lacking many many things. C++ will still be around in
30+ years. But remember, C++ has a good 10 year head start on java, and java
gained a lot of traction because of all the tools they didn't have to build.

Nobody needs to build valgrind for rust (or your favorite alternative).
Leveraging existing libraries isn't trivial, but it's not a year long project
either. IDE's support a lot of languages out of the box. rust support will be
rough at first, but quality will be proportional to use. I suspect microsoft
could build the layers you want like they did with J++ very quickly. A year?
maybe 2?

The biggest bottleneck, imho, is developers. I don't think many people really
_know_ all the dark and scary corners of C++, but there are a ton of people
that can get stuff done in C++.

If schools start graduating people with rust experience, the writing is on the
wall for C++. Shifting school curriculum takes a big reason. Maybe a hit indie
game, maybe some other killer app. I don't think servo is the one.

Really, it's a testament to the quality of the language that the complaints
are all along the lines of "it's fantastic, but the tooling..." Don't
underestimate that. Tooling can happen real fast.

Is rust a sure thing? no. absolutely not. does it have a chance of becoming
_the_ systems programming language in 10 years? Yeah. i think it does. i think
it's got better than a 5% chance of doing that. 1 in 20 is a perhaps an
insanely high number. The language is just so very good.

~~~
pmelendez
>"But remember, C++ has a good 10 year head start on java, and java gained a
lot of traction because of all the tools they didn't have to build"

The thing is... I don't think Java took over C++ developers. Most likely they
took over Pascal, Delphi, VB, Perl and other enterprise developers.

Every decade there is a language that claims to kill C++ (Java in the 90's, Go
in the 2000's) offering features that are not bothering C++ developers and end
taking off by attracting developers from other communities (like Go with
Python devs).

I believe that memory safety or manual memory management is not the mainly
concern for a C++ developer. On the other hand, if you give the same tools
that C++ has and reduce complexity and then you might got into something,
until then...

~~~
tamana
You are forgetting that Enterprise WAS C++ before Java.

Amazon went from C++ (to Perl) to Java.

Google went from C++ to C++/Java (and now Python and then Go)

Microsoft went from C++ to C++/C# , C# is Microsoft flavor of Java.

~~~
ausjke
In certain areas such as games, GPU, etc C++ still rules, which is why I
restarted on c++ nowadays.

------
Animats
I 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
You 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
The idea that you can find a sane subset of C++ is itself insane.

~~~
nickpsecurity
Really?

[https://news.ycombinator.com/item?id=11895686](https://news.ycombinator.com/item?id=11895686)

~~~
catnaroek
From your linked post:

>
> [https://www.cis.upenn.edu/~eir/papers/2013/ironclad/paper.pd...](https://www.cis.upenn.edu/~eir/papers/2013/ironclad/paper.pdf)

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/selectp...](http://research.microsoft.com/en-
> us/um/people/marron/selectpubs/Undangle.pdf)

Have you actually read the paper? This isn't a static analysis at all. It just
makes a dynamic analysis more eager and precise.

~~~
nickpsecurity
Appreciate insight on first link. Far as other, that's my mistake given I only
read parts on anslysis, diagnostic, and performance. It was in a list of
static anslysis stuff I found. So, I wrongly assumed it was static analysis
instead of verifying it myself as I did first one on that page [that worked
but had limitations].

------
makecheck
I’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.

~~~
chubot
But which scripting language? C++ header are fairly hostile interfaces for
wrapping. You end up with either tons of hand-written glue code or littering
your header files with annotations so they can be sorta wrapped.

Python is not very good as an embedded language (globals and locks). Lua is OK
but AFAIK making C++-like classes in Lua is a pain, and the language is a bit
annoying for other reasons.

~~~
_nalply
Which reasons?

~~~
chubot
IIRC, if you make a typo in a var name in Lua, you don't even get an exception
like Python -- you just get nil. I'd prefer it to be more strict about errors
like that.

1-based indexing. Prototypes rather than classes -- I don't think having to
roll your own or research an object system for every project is a good use of
time.

Lua is a great language implementation, but whenever I try to actually program
in it, it feels like an inferior version of Python...

------
2bitencryption
The 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.

~~~
Flow
There are plenty more warnings to turn on than what -Wall uses.

[http://stackoverflow.com/questions/11714827/how-to-turn-
on-l...](http://stackoverflow.com/questions/11714827/how-to-turn-on-literally-
all-of-gccs-warnings)

~~~
2bitencryption
unfortunately it passes -Weverything on clang, as well.

------
nickpsecurity
It's not vapourware: it's called Ironclad C++ and it's on Github. :)

[https://www.cis.upenn.edu/~eir/papers/2013/ironclad/paper.pd...](https://www.cis.upenn.edu/~eir/papers/2013/ironclad/paper.pdf)

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

------
catnaroek
Agreed 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-...](http://axisofeval.blogspot.com/2011/01/why-lisp-is-big-hack-and-
haskell-is.html).

“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
The article you link starts with:

> 2013 Update: I was young and stupid when I wrote this.

~~~
catnaroek
Which 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
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.

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

~~~
coldtea
No, it's those things called "opportunity cost", "pragmatism" and
"ecosystem"...

------
cLeEOGPw
I 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.

~~~
xg15
Those 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
There 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.)

~~~
leni536
> * Technically not any, due to Gödel's incompleteness theorem

Sorry, but it's not true, see Gödel's _completeness_ theorem. It basically
states that any "true" statement is provable. So you can verify any correct
code as correct. There are problems if you try to verify a not correct code as
correct though.

~~~
rntz
Godel's completeness theorem applies to first-order predicate logic, which is
not powerful enough on its own even to _express_ , let alone _prove_ , 1+1=2.
First order logic is best thought of as a framework on which other, useful
logics may be built. And as soon as you add enough power to first-order-logic
to capture Peano arithmetic, you run into incompleteness.

C++ behavior is almost certainly more complex than Peano arithmetic.

------
saynsedit
Rust is better than C++

