
We have C++14 - ingve
http://isocpp.org/blog/2014/08/we-have-cpp14
======
daenz
When I started writing C++ around 5 years ago, I had a perception that it was
a language that is "on its way out". As I learned more and more of it, I've
been super impressed at how modern it is becoming, and how it is adapting to
overcome its perceived flaws. It is becoming a killer language to me: blazing
fast, modern, ubiquitous, stable, and expressive.

~~~
PopsiclePete
Too bad it's a mirage. No, really. "Modern C++" doesn't exist outside of blog
posts, books, and tutorials.

Real-world C++ is an array of sometimes mututally-exclusive dialects,
patterns, rules, sub-dialects.

Reading MFC is nothing like reading Qt which is nothing like WxWidgets which
is nothing like Boost which is _something_ (but not quite like) the STL which
is way different from Apache C++ libs which is way different from what
Google's C++ libraries are...

This is what happens when a language is "un-opinionated", throws everything
including the kitchen sink at the language, tries to compile C and legacy C++
while introducing new features oh and also can't break existing code.

It's on its way out, no doubt about it. And we'll be better off as an industry
for it, I'm sure of it.

Rust, Go, and others will be there to fill in the gap in a much better, saner,
safer, maintainable way.

~~~
davvid
_Too bad it 's a mirage_

I hate to spoil your worldview, but modern C++ is very alive and well in the
scientific computing communities. Disney Animation implemented a new renderer
using it, and our next movie is currently being rendered using the new
renderer, so I highly doubt it's on its way out in the these areas.

~~~
enraged_camel
I don't see how that refutes the parent's comment. The areas you listed are
very small niches. Frankly, very few people care about scientific computing or
even animation rendering. Generally speaking, using C++ is like wearing jeans
and white sneakers: popular in the 90s, but definitely out of fashion now.

~~~
72deluxe
Why do you need to be fashionable to be productive? Do people really ask what
your finished software product is written in?

------
pjungwir
OT question: I was playing with some C over the weekend (not C++), trying to
figure out how to handle Unicode in a way that would work on Mac, Linux, and
Windows. Despite a couple hours googling and reading, I couldn't answer really
basic stuff, like:

\- Do I use char* for strings? It sounds like wchar_t is 16 bits on some
systems and 32 on others, so I should avoid it?

\- If I want to read & write UTF-8 files, how do I turn the bytes into 32-bit
wide Unicode strings?

\- Are there special functions I should use for handling Unicode strings?

More generally, where do you go to discover C libraries you can use?

I am (was) reasonably proficient in C, but I haven't used it much for over ten
years. I'm surprised how many things I just don't know how to do!

Sorry this is not a C++ question. I'd like to get back into that also, but I'm
trying to work my way up from the basics. :-)

~~~
zanny
Why not just write C style C++? I never understand the arguments to use C
anymore - you can write C style C++ and get on with your life, and cherry pick
the features you want.

In C++ unicode is as simple as: string s = u8"This is always a utf8 string.";

~~~
antimagic
Weeellll, your position is defensible if you're writing an application. If
you're writing a library though, let me just let you know that every time I
encounter a package with a C++ API, I want to drive stakes into the author's
eyes, as compensation for the pain _I 'm_ about to experience.

Like it or not, C is the lingua franca of the programming world. Pretty much
every other language out there provides C bindings, not C++ bindings. Which
means that when your function exports something wonderful like smart pointers,
_my_ world just becomes painful.

Furthermore, in embedded environments, it can be challenging (to use a
euphemism) to get source code debugging up and running. If your code is
written in C, it's not so bad, non-optimised machine code generated from C
tends to match the actual C code fairly closely, to the point that you can
very nearly read it as easily as the original source. This is not true for
C++, which means that every time something goes wrong in C++ code, I'm
probably going to lose a week of my life inserting trace into the code,
compiling, deploying to target, and running the test, ad infinitum. Not fun.

Even in the case where you're writing an application, I'm personally dubious
about the benefits of C++. Write the application in a higher-level language,
personally I like Javascript (JavaScriptCore) for this, but I've had good
success with Ruby and lua as well. When you hit a performance bottleneck, push
the performance sensitive code into C, and create bindings. As a bonus, your C
code is now easily available to be used as a library from any other language,
without inducing homicidal tendencies in the user.

~~~
zanny
extern "C" {

}

Hey look, C API.

> This is not true for C++,

Depends on the code you write. If you write C in C++, you get the same near
machine parity, since its the same source material. If you do not use
namespaces you don't even get name mangling.

------
nly
You can grab and compile the very latest _draft_ from the committees Github
page:

[https://github.com/cplusplus/draft](https://github.com/cplusplus/draft)

The current version is a slender 1365 pages, including the standard library.

------
Guthur
I see a lot of discussion around C++ becoming modern. I would like to know
which features are actually modern?

Is it lambdas? been around for literally decades. Is it type deduction? again
been around for quite some time, far better type inference has been available
in the likes of Haskell for quite some time. Is it addition of a particular
threading model to the standard? this has always been available via some form
of library, it just know means the language is truly obsolete if the model
changes. Allow GC'd implementations? again decades.

What is modern about any of features that have been added?

~~~
claudius
> What is modern about any of features that have been added?

Nothing. On the other hand, which features of a “modern” language are missing
in C++ by now? Type deduction is still a bit less powerful than in Haskell,
yes, but apart from that I can’t really think of anything that may or may not
be missing.

This in turn implies that C++ allows essentially any style of coding you may
wish for at the moment while at the same time staying some orders of magnitude
faster than essentially the entire competition.

~~~
Guthur
C++ is no faster than any other language, it's the code that is written which
is measurable.

The real wins in performance for real world applications are in terms of
algorithmic complexity. A poorly implemented solution in C++ will still be
slow, the language does not make it fast.

Any micro optimization you can make with C++ will be an order magnitude less
significant than O(log n) vs O(n).

The likes of Janestreet will likely need high performance software yet have
great success with Ocaml for example, which incidentally can be very fast.

Just saying C++ is fast does not make programs written in C++ actually fast.

~~~
claudius
> The real wins in performance for real world applications are in terms of
> algorithmic complexity. A poorly implemented solution in C++ will still be
> slow, the language does not make it fast.

Yet a well written implementation in C++ will still be faster than an equally
well-written implementation in, say, Python or Haskell or whatever. Not in an
asymptotic sense, but easily by a factor ranging between two and 200. For me,
this can be the difference between waiting a couple of weeks or half a year
for some computation to complete :)

> Just saying C++ is fast does not make programs written in C++ actually fast.

Of course not, but C++ makes it possible for programs written in C++ to be
fast.

~~~
pkolaczk
Comparing to Python or Haskell, maybe you're right, but not to CLR-based or
JVM-based statically typed languages. Very often the differences between
Java/C# and C++ are the same order of magnitude as differences between various
C++ compilers. The mythological C++ performance is often overstated (there are
_some_ performance advantages in C++ but they are rarely big enough to justify
language choice).

~~~
deong
An order of magnitude is a hell of a lot. I did some extensive comparisons of
C++, Java, and C# back when I was working on my dissertation. Admittedly, this
was about 10 years ago now, but at the time, the best I could get with Java
was about a factor of 2.5 slower than C++. C# was similar, but I don't recall
the specifics now.

When you read a language shootout, a lot of times a factor of 2-2.5 times
slower than C or C++ is considered to be "good enough". If you get your
Clojure code that fast, everyone calls it a day. For me, a typical run of my
experiments took about 3 weeks on (I think) a Core 2 Quad using all four
cores. So in the best optimized Java I could find, that would have been about
_5 extra weeks_ spent waiting around for results, and I had several cycles
like that. All told, I imagine it would have added a year to my work.

I'm not necessarily picking on you here. You did say "rarely", not "never".
But I don't think a lot of people are aware of how common it is for a factor
of two to be a complete deal-breaker.

~~~
pkolaczk
A factor of two difference is something that can be a result of using
different C++ compilers or even different versions of the _same_ compiler.

See this: [http://lemire.me/blog/archives/2012/07/23/is-cc-worth-
it/](http://lemire.me/blog/archives/2012/07/23/is-cc-worth-it/) Particularly
the comments section contains various results obtained from different
compilers / versions. Variablility is higher than 2x for GCC.

Comparing with Clojure is not fair, because it is not really statically typed,
and known to be much harder to optimize for speed than e.g. pure old Java.

~~~
deong
I tossed out Clojure as a random language -- all my testing was done with the
most efficient Java and C# I could write.

The link is fine, but only shows micro-benchmarks. It's much easier to get a
3x difference in execution speed between compiler versions when you have a
three-line example -- you're maybe exercising 5% of the optimizer?

The current version of the C++ I was using comes in at around 50kloc. The Java
and C# versions were a bit smaller, since once I stopped testing the
platforms, all the new code only went into the C++ version, but it's a
significant piece of work. I haven't seen any significant real application for
which the theoretical benefits of Java (JIT's profile-guided optimizations,
etc.) have really come to pass. You can write slow C++ code, but if you know
what you're doing and instrument carefully, there's very little or no evidence
that Java can be as fast on real programs.

~~~
pkolaczk
> It's much easier to get a 3x difference in execution speed between compiler
> versions when you have a three-line example

Those three lines can be as well a bottleneck in a big program, responsible
for 80% of its runtime. This example was to show that compiler-induced
performance differences in a single language can be just as large (here: up to
4x) as differences between Java and C++ in microbenchmarks. Therefore 2x
difference in a microbenchmark where Java is losing to C++ is probably not a
statistically significant difference, even though it may be important to the
end user. If you rerun this benchmark in 3 years from now, using newer
versions, you might as well get completely different results.

As for real applications - that you don't know of any real, fast Java program,
doesn't mean there exist no evidence. Sure, it is quite hard to find a pair of
two programs doing exactly the same written in two different languages, but
there do exist quite a few high-performance Java apps out there which are #1
in their class: Netty, Apache Cassandra, Apache Spark, LMAX disruptor (Java
used for ultra low-latency app, see:
[http://programmers.stackexchange.com/questions/222193/why-
di...](http://programmers.stackexchange.com/questions/222193/why-did-the-team-
at-lmax-use-java-and-design-the-architecture-to-avoid-gc-at-all)). Someone
also ported Quake2 to Java (Jake2) just to show it was possible, and that
didn't make it slower.

~~~
deong
I'm not saying there's never a use case for Java. It's reasonably well suited
for server-side work (and most of your examples are IO-bound server
processes).

When your main problem is IO, thread contention, etc., Java gives you better
tools to address those problems. It's just not at all well suited for the kind
of client apps that people run on their desktop computers, and to a lesser
(but still visible) degree, it's not well suited for CPU-bound things like a
lot of scientific computing, which is more where my expertise lies.

Looking at Jake2, the author notes: "The 0.9.2 release shows a big improvent
due to the new “fastjogl” OpenGL renderer. The new renderer reduces the number
of native interface calls. JNI calls produce a considerable overhead and were
the main bottleneck in our application." If he's doing enough JNI to make this
the main bottleneck, then clearly quite a lot of the heavy lifting isn't being
done with Java.

------
lelf
Recent standard draft (2014-03)
[https://github.com/zygoloid/cplusplus/blob/master/papers/N39...](https://github.com/zygoloid/cplusplus/blob/master/papers/N3936.pdf?raw=true)

~~~
yelnatz
Do you know where I can find a diff?

I'd like to see whats new with 14.

Edit:
[http://en.wikipedia.org/wiki/C%2B%2B14#New_language_features](http://en.wikipedia.org/wiki/C%2B%2B14#New_language_features)

------
bnejad
Can anyone recommend a book on modern C++?

~~~
dfan
Scott Meyers' _Effective Modern C++_ will be required reading once it's
released in October.

Until then (and even after), Stroustrup's _The C++ Programming Language_ (4th
edition) is the canonical resource. It's a reference but is also intended to
be read.

~~~
Roboprog
Ironically, it was (the first edition of, I believe) Meyer's "Effective C++"
that made me question "WTF? Why does anybody use this???" (given that Turbo
Pascal / Delphi, or Perl, actually were much easier to understand). Maybe C++
is usable now, but back in the late 90s, nobody that I respected used C++ -
all the code I saw at work in C++ was by resume padding morons who wouldn't
recognize polymorphism if it walked up and bit them in the ass. (the opinion
being either use C, or a high level language, but not C++)

Not fair to judge the language by the fools that used it 15+ years ago, but I
have no use for operator overloading, copy memory leaks and all the other C++
obfuscation.

C++ _would_ probably benefit from a "lessons learned" do-over with a new name
(as referenced elsewhere in the Perl 6 / Python 3 debacles)

------
jastanton
I apologize if this is ignorant, but how is C++ versioned?

~~~
spott
what do you mean?

C++ is a language designed by committee. C++14 is meant as a "tock" release,
fixing some of the things in the C++11 "tick" release. ("tick" releases are
larger, and "tock releases fix some of the problems in the "tick" release).

Compilers then attempt to implement the standard, and have their own
versioning system.

~~~
StephanTLavavej
Traditionally, "ticks" are small, and "tocks" are big. See
[https://en.wikipedia.org/wiki/Intel_Tick-
Tock](https://en.wikipedia.org/wiki/Intel_Tick-Tock) .

------
cletus
I've started getting back into C++ after many years away and it's all coming
back to me.

Now of course it's C++11, which does have some nice features, but really I
think we've reached the point where we need to start again (downvote away).

Let me give you an example: I recently came across some code that was written
years ago that has two size types: one 32/64 bit signed and the other 32 bit
unsigned. This creates a bunch of issues when compiled on 32 and 64 bit
architectures and there is a substantial amount of effort to clean it up.

I point out things like this to colleagues who are very pro-C++ and I
inevitably get the same response: "well that's just bad API design".

Thing is, if you look at the history of this example it's a series of
incremental changes, all well-meaning and reasoned, some of which are done by
people who I could only call luminaries, and even they make significant and
far-reaching mistakes.

So what hope do the rest of us have?

But my biggest problem with the C-dialects is pointers. Namely if you return
or receive a pointer, it's not necessarily clear who owns it. The way this is
handled is comments like "DO NOT delete this" or "you MUST delete this".

I like that a language like Rust is trying to formalize the concept of object
ownership. I'd really like to see that idea mature and take hold.

Until now there hasn't really been a competitive alternative to C/C++. It's
not Go (as much I love Go). Maybe it's Rust. We can but hope.

My other big problem (and this applies to Java too) is directly dealing with
low-level multithreading primitives like threads, thread groups and mutexes. I
really like that Go has taken a different approach here.

What I find with particularly young programmers is they don't have the
appropriate fear of writing multithreaded code. It's really, really hard to
write correct multithreaded code with low-level primitives. It's why
(excellent) books like _Java Concurrency in Practice_ exist.

As for the feature list of C++14 [1], I wonder what all these "auto"
declarations will do to the significant work required for static analysis
tools, that are an essential part of modern, large-scale C++ codebases.

The literal types (like "s" for std::string or seconds) are cute but at some
point the STL was optional. I'm a little leery of embedding it directly in the
language but hey I'm no expert.

[1]:
[http://en.wikipedia.org/wiki/C%2B%2B14](http://en.wikipedia.org/wiki/C%2B%2B14)

~~~
deathanatos
> code that was written years ago that has two size types: one 32/64 bit
> signed and the other 32 bit unsigned. This creates a bunch of issues when
> compiled on 32 and 64 bit architectures and there is a substantial amount of
> effort to clean it up.

Such things happen whenever an invalid assumption that is commonly true
becomes not so commonly true, such as the 32-bit to 64-bit migration. That
said, C/C++ provides you the tools: size_t is an unsigned type meant for
storing array indexes and the size of objects in memory. If you want a real
integer, then (unsigned) int. If you need integers of a definite fixed size,
u?int(8|16|32|64)_t. Granted, I've encountered that not enough people take the
time to understand the tool they're using. Honestly, I wish the default
integer type was not fixed size, and especially not platform dependent fixed
size, like Python; for non-[indexes/sizes], I feel like this is usually what
you want.

> "well that's just bad API design".

Well…

> But my biggest problem with the C-dialects is pointers. Namely if you return
> or receive a pointer, it's not necessarily clear who owns it. The way this
> is handled is comments like "DO NOT delete this" or "you MUST delete this".

This is true; in C++, your use of pointers should be minimal, though this can
be a problem with references just as easily. In the (special) case of
std::shared_ptr, ownership is clear. That said, this is a problem not unique
to C++: it exists in Java, Javascript, Python, and many others as well. For
example,

    
    
        some_list = [1, 2, 3]
        some_obj = MyObject(some_list)
    

If some_obj expects to own that list, and it's constructor is:

    
    
        def __init__(self, some_list):
            self._some_list = some_list
    

which I see a lot, you've got the same problem. (I'm also interested to see
how well Rust tackles this, as I agree it's a problem.)

> My other big problem (and this applies to Java too) is directly dealing with
> low-level multithreading primitives like threads, thread groups and mutexes.
> I really like that Go has taken a different approach here.

Honestly, I've never thought multithreading was "hard". There's a set of rules
you have to hold yourself too, otherwise, yes, you can make your life very
hard. If you limit shared data as much as possible, and what data is shared
has a well defined locking order (preferably behind code that enforces it) —
often this is just a single mutex — then I don't see the problem. Thread-safe
queues ("channels", I think Go calls them) are also useful to establish
"service" like threads.

~~~
bad_user
There's no such thing as a well defined locking order - a statement that
should scream the fact that locks are not composable. Good luck documenting it
in the API or in making other developers pay attention.

The problems are even worse than with manual memory management, since there
you often get away with RAII. Say a function call is returning some sort of
list, or some other data structure. Was the producer operating on another
thread? Was that data structure signaled to other consumers as well? Can you
modify it without locking?

To make matters worse, locking is extremely inefficient, it limits the
possible parallelism, throughput and vertical scalability and suddenly you
start thinking of not protecting reads, since shared reads should be
parallelizable, right? And so you need to look at alternative means of
synchronization and then suddenly you end up reasoning about happens-before
relationship arising from usage of memory fences, non-blocking algorithms and
single producer / multiple consumers scenarios. And then you discover that C++
doesn't have a strong memory model to speak about and that at least before
C++11 it was all platform dependent.

Of course, I like this state of things, since my favorite platform (not C++)
has a better memory model and plenty of higher level abstractions built on
top, like actors, CSP, ring buffers, futures, Rx, iteratees, immutable data-
structures, etc... but yeah, people able to reason about concurrency are also
avoiding it like the plague.

------
pjspycha
Number one wishlist item for next C++ is to add networking libraries to the
STL. Its past time that C++ knew about the internet.

------
selvan
C++ is suitable for development of cross mobile applications , since both iOS
and Android tool chain has support for C++.

------
jokoon
Are modules already kind of unofficially supported, or can they be enabled ?
On what platforms ?

I'm trying to make a C++ game with fat libraries like Ogre3D and bullet3D,
often on a laptop, and that would really be fantastic to not wait 10s or more
each time I edit a header.

I've seen a presentation, basically modules would decrease compile time from M
x N to M + N.

------
spott
I really like the direction C++ is moving in. I just really don't like how
incredibly VERBOSE it is (though `auto` helps).

~~~
astrodust
In languages like C++ "verbose" means "specific and obvious" which is
something you want to have when writing certain kinds of code.

It's annoying, it's a drag on productivity, but in the long run it's arguably
necessary.

Some other languages which reduce verbosity by making more things implicit
make it harder to understand what's actually going on behind the scenes. You
lose a lot of information.

~~~
ajuc
A lot of C++ verbosity comes simply from bad defaults. Const and virtual
should be the default for example, not the other way around. Would stop the
virtual destructor ommision problem, and if you need efficiency you could make
destructors non-virtual.

Also in the "hiding stuff behind the scenes" department C++ is quite bad.

    
    
        SomeClass someMethod(SomeClass a, SomeClass b) {
            ...
        }
    

is doing a lot behind the scenes. Code below is better but it's longer and
less convenient to write.

    
    
        const SomeClass& someMethod(const SomeClass& a, const SomeClass& b) {
            ...
        }
    

And actually C++ code isn't easy to reason about wihtout reading the whole
program. It isn't even easy to parse.

What's going to happen when you run this?

    
    
        y = f(x);
    

It may be that f is function, or a type. f may return the correct type to
assign to y, or it may return something else and automatically run some
conversion. There may be copy constructor and some destructors involved if
it's returning object and not reference. It may run overloaded operator= and
do anything at all, for example add f(x) to y. Hell, f can also be a class
with operator() overloaded, and you would need to track its state to see what
will happen.

And we haven't even touched the subject of #define.

It's much easier to reason about Java code for example.

~~~
wfunction
Uh, no, "virtual" should absolutely NOT be the default. I don't know where you
got that idea from (Java?) but it's absolutely horrible.

~~~
zak_mc_kracken
It was the right default twenty years ago for performance reasons.

These days, the economy of a vtable pointer is not really a good reason, and
all languages that have the opposite default (such as Java, as you point out)
are doing quite fine.

Because of this default, I can't count the number of times where I've seen
"#define private public" and other horrors that developers used to be able to
extend classes that their creators were too short sighted to design properly.

~~~
jonstewart
I'm very glad that virtual is not the default. Most of the classes I write are
simply value classes and do not use inheritance at all. Once you start using
virtual, you really have to embrace traditional inheritance idioms whole hog,
and then you've got std::vector<std::shared_ptr<Foo>> instead of
std::vector<Foo>.

If anything, the performance difference between std::vector<shared_ptr<Foo>>
and std::vector<Foo> is even greater today than it was twenty years ago.

~~~
ufo
On the flipside, if you are not using inheritance then you could have solved
the same problem with abstract data types. The only big problem is that in C++
the method call syntax is much more convenient to use: foo.frob() vs
Foo::frob(foo). IMO, the correct way to fix this is by adding syntax sugar to
the language, not by making methods non virtual by default.

~~~
jonstewart
I don't understand. Do you mind elaborating? Not sure what you mean,
specifically, by "abstract data type" (I think of ADT as just another synonym
for a class), nor do I get the static method thing. If you were calling hard-
coded static methods, you wouldn't have polymorphism anyway, so how you have
virtual methods?

------
hit8run
And we have golang.

------
phkahler
I'm a little afraid the language will go down hill from here. Too many
versions - a committee dedicated to creating new versions of the language
standard is going to do exactly that. Much like has happened with OpenGL.

~~~
_pmf_
> Too many versions - a committee dedicated to creating new versions of the
> language standard is going to do exactly that. Much like has happened with
> OpenGL.

The problem with OpenGL was that they tried to retrofit an API that assumed a
certain underlying hardware model to modern (i.e. less than 15 year old) GPUs.
It was impossible to do in any sane manner.

------
DeadClan
I'm assuming C++14 will have 1320 keywords and a bunch of weird operators to
use so people can ignore it even more than it's being ignored.

~~~
cdelsolar
um, C++ is the most widely used language in the world.

~~~
tormeh
Okay, that's incorrect. It's a bit hard to say whether it is Java, Javascript
or C, but it's certainly not C++.

~~~
tedunangst
It's really neither here nor there, but every java or JavaScript engine in
widespread use is written in c++, so c++ code "in use" subsumes both of them.

~~~
tormeh
No language exists but x86 binary code!

~~~
AnimalMuppet
Um, ever hear of ARM? (Also 680X0, IBM mainframes, 8051, Itanium, Sparc...)

But then I presume the parent was sarcasm.

~~~
tormeh
Yeah, it was sarcasm on my part, at least. Point being that only binary is
it's own language all the way down (which is of course not long at all).

