
Bjarne Stroustrup Discusses C++ - DmitryNovikov
http://electronicdesign.com/dev-tools/interview-bjarne-stroustrup-discusses-c
======
nkurz
Stroustrup says:

    
    
      The real novelty here is the return statement: Note that
      I return a potentially huge vector by value. In C++98,
      that would typically cause the copy of all elements of
      res, potentially many thousands of elements. That would
      be a serious performance bug. In C++11, vector has a
      “move constructor,” so that rather than copying elements,
      the representation of res (merely three pointers) is
      “stolen” for use in the caller and an empty vector is left
      behind. After all, we are just about to return from 
      find_all() and won’t be able to use res again. Thus,
      returning a vector by value costs at most six word
      assignments independently of the number of elements.
    
      Move constructors is a simple facility available to every
      programmer and used by all standard-library containers
      implemented as handles. This allows us to return large
      objects from a function without messing around with
      memory management (explicitly) using pointers and
      free store.  
    

Are most C++ programmers excited by this? Is the idea that people should start
writing code depending on this behind the scenes behaviour, or that we now
have a way to speed up poorly written code? It feels like an awful lot of
effort to avoid returning a pointer. And if I were actually worried about the
performance, I wouldn't feel comfortable just hoping it happened. Is there any
confirmation by the compiler that it handled this in the way the programmer
wanted?

~~~
yoodenvranx
I am not that good at C++ so it would be really nice if somebody can enlighten
me:

Isn't this already the case with some (all?) compilers in pre-C++11?

[http://www.parashift.com/c++-faq/return-by-value-
optimizatio...](http://www.parashift.com/c++-faq/return-by-value-
optimization.html)

~~~
eliasmacpherson
NVRO works by constructing the object once... (EDIT: detrino points out this
is wrong, the object is not constructed first before passing, it is only a
memory address that is passed, it's the return value that is constructed on to
this address)

It is passed as a hidden argument to the function, assigning the return value
to that argument passed in. Prior to the NVRO, the object was constructed
once, a temporary was constructed and then copy constructed to give the
result. You can test out the NVRO yourself by putting a printf in an object's
constructor, and have the object returned from a function on to an object of
the same type.

Stan Lipmann's Inside the C++ Object Model explained it best for me. NVRO
applies to the vector object.

The difference here is that Stroustrup is talking about the elements of the
vector, not the vector itself, and how the move semantics remove the need for
constructing/copy constructing them.

~~~
detrino
What you are talking about is really just the calling convention common on
many machines. When you have a function returning a struct, what really
happens is that the return address for the struct is passed as an extra
argument. No construction of the struct happens prior to this, its just an
address. Compilers are able to take advantage of this calling convention in
many cases to elide copies, and the result is RVO/NRVO.

~~~
eliasmacpherson
Are you alluding to some sort of hardware mechanism by mentioning machines? In
what context are calling conventions machine dependent?

The reason it's notable in C++ is because the code that would normally be
called in the constructor is not called as many times as the person writing
the code might expect.

In C++ structs can have constructors, but usually have an empty default
constructor supplied by the compiler, this is more of an issue when
structs/classes have user supplied constructors.

Here's an article giving more specifics of the history of NVRO from Stan
Lipmann. Interestingly, NVRO was not added to Visual C++ til 2003, and Lipmann
prefers NVRO off by default. I think I recall an NVRO flag in that compiler.
NVRO was available in cfront and Zortech compilers in the early nineties. [1]

[1]
[http://blogs.msdn.com/b/slippman/archive/2004/02/03/66739.as...](http://blogs.msdn.com/b/slippman/archive/2004/02/03/66739.aspx)

~~~
detrino
The calling convention your compiler is using is dependent on a number of
things [1]. It is this calling convention that dictates how values are
returned from a function, not whether or not RVO/NRVO is happening. Also, what
is being passed as an extra argument, according to many calling conventions,
it not really an already constructed object, but an address for an object to
be constructed into. Under certain situations the compiler is able to elide
copes, which as you pointed out, leads to your copy constructor to never be
called at all, even if it has visible side effects. I think these are
important distinctions and hoped pointing them out would be beneficial.

[1]
[http://en.wikipedia.org/wiki/X86_calling_conventions](http://en.wikipedia.org/wiki/X86_calling_conventions)

~~~
eliasmacpherson
Yes, thanks for pointing the calling conventions out, I didn't really know
what you were getting at.

The hardware calling convention does dictate certainly what code the compiler
can put out.

If the compiler does not support NVRO and emits code that causes multiple
copy/constructions it doesn't matter if the hardware supports more efficient
behaviour.

I edited my earlier comment with your correction, thanks.

------
fhd2
I'm sort of a C++/Stroustrup fan I guess, but this confused me:

> C isn’t simpler for C-style programming than C++ is [...]

Is Stroustrup really arguing that C is not simpler than C++? How can it not be
simpler? C++ is essentially C with a ton of features added on top.

~~~
eliasmacpherson
That whole paragraph is ridiculous. I'm commenting but really I should abstain
because I feel I am lowering the tone with yet another great religious debate:
C vs. C++.

"No. C isn’t simpler for C-style programming than C++ is, nor “closer to the
hardware,” nor indeed more efficient. I have yet to see a program that can be
written better in C than in C++. I don’t believe such a program could exist.
By “better” I mean smaller, more efficient, or more maintainable."

Firstly, I'm sure what he's writing there is predicated on the C++ STL being
available, the use of which will in turn increase compilation times, because
there's a lot of templated code to compile.

I cannot see how you would implement strlen or malloc in C++ (EDIT: as
efficiently and/or) more efficiently than C, particularly when you take
casting void into account. It's not a far stretch then to imagine writing
drivers and so on, where idiomatic C++ would be a distraction compared to C.

In the above his metrics, smaller, more efficient, more maintainable - I can't
see any features that C++ has that will allow them to be proven true.

Any program that has to interact with a C library - Stroustroup would suggest
library then to be wrapped to make it behave according to C++ style - if so -
if the code is just calling a few library functions, C will be shorter and
better by all his metrics.

The most convincing is maintainability, but C++ has many more ways to skin a
cat than C, so where C had the overhead of understanding someone else's data
structure, C++ pretty much does too.

~~~
CJefferson
Firstly, you can always assume the "C++ STL" is present, it is part of C++.

While implementing strlen faster in c++ is harder, implementing qsort faster
is easier, as you have the option of compiling a version with the size of
type, and comparator, known and inlinable.

Also, you could use a constexpr version of strlen on strings known at
compiletime, and be sure the compiker will optimise out the call, unlike in C
where you just have to hope the compiler will

~~~
eliasmacpherson
Thanks for your reply. You can assume it's available in a general sense but
you may not be allowed to use it, sometimes this happens.

Stroustrup made a bold claim that no program exists, I pointed out strlen and
malloc - that there exist programs that can be written more efficiently by his
metric - your e.g. qsort, I do not dispute, but I refuted his claim. I didn't
say implementing strlen faster, I merely said implementing strlen is not by
any of his metrics a superior experience in C++.

C would just use hardcoded strings or defines, with sizeof(). This is also a
possibility in C++, but I was talking about the implementation of strlen not
the usage.

~~~
adwn
Neither strlen nor malloc (nor qsort) count as programs under any pragmatic,
non-nitpicking, definition.

Even the assumption that implementing, e.g., a memory allocation algorithm in
C++ is not more comfortable than in C, does no lead to the conclusion that
writing a device driver (your example) in C++ is not more comfortable than
doing it in C.

~~~
eliasmacpherson
I agree with you. Just to be clear: I'm not making bold statements like "I
don’t believe such a program could exist.".

But you do admit they are programs! That was all I was trying to do, refute
his ridiculous claim - albeit with something marginally less ridiculous. How
about a program calling a C library?

The driver thing doesn't automatically lead to the conclusion - but it's not a
far stretch to picture it being so. A simple thought exercise does not make a
water tight argument.

I can imagine writing certain parts of drivers being better under his metrics
in C++ than C but I don't see it in black and white terms like he does. I can
see the opposite being the case also.

All that needs to happen for Stroustrup to be wrong is for one program to
exist that beats his metrics in C instead of C++.

~~~
adwn
> But you do admit they are programs!

No, I don't – not in the sense that Stroustrup was using the term "program".
strlen or malloc are not programs in the way that this term is commonly
understood. His claim is not ridiculous, unless you're nitpicking by using
definitions which are just not useful for the discussion at hand (i.e., is C++
better suited for developing non-trivial software).

As for the driver example: I guess we'll just have to agree to disagree,
unless someone actually implements a device driver in C and in C++ ;-)

~~~
eliasmacpherson
At least we can agree that a driver is non-trivial. How about a program that
calls a C library?

The only project I know of that publishes in multiple languages, vtd-xml - the
C++ library has 40k lines of code versus C which is 60k. I don't dispute that
C can be more verbose - but it's not a stretch of the imagination to think
there's a program somewhere out there that meets Stroustrup's requirements
better in C than C++.

Not sure at what point we will have a certain agreement on what is trivial and
what isn't. Here's an example of someone writing a lot of code to wrap a C
library in to C++, and then doing a few calls to it.

[http://www.codeproject.com/Articles/6343/CppSQLite-C-
Wrapper...](http://www.codeproject.com/Articles/6343/CppSQLite-C-Wrapper-for-
SQLite)

------
azov
For the sake of balance, here is Yossi Kreinin's list of things that are wrong
with C++:
[http://yosefk.com/c++fqa/defective.html](http://yosefk.com/c++fqa/defective.html)

PS. One of my biggest gripes with C++ is the lack of uniformity. Not only the
language itself has insane learning curve, every project does so many trivial
and not-so-trivial things differently that it's like learning another language
each time you dive into a new codebase. From code formatting, documentation,
and source tree layout to error handling, libraries and build system - for
something so huge and complicated as C++ there's an amazing number of
batteries _not_ included. Even the things that are supposed to be standard in
theory are often not so in practice. Damn, there's _still_ custom string
classes in the APIs of many popular libraries - almost two decades after
std::string and STL!

PPS. And yes, there's a difference between having consistent conventions and
trying to be perfect for everybody and everything.

~~~
stinos
or as bjarne points out in the article _There can be no programming language
that is perfect for everybody and for everything. C++ doesn’t try to be
everything for everybody, but it is rather good at the tasks for which it was
designed – mostly systems programming, software infrastructure, and resource-
constrained applications_ and _Don’t just say “I want a GUI library” or “there
is no proper support for task-based concurrency” or whatever. We know that._

~~~
pkolaczk
Yet, most operating systems have been written in pure C, resource constrained
applications are still being written mostly in pure C or eventually C with
classes (and mobile apps are _not_ resource constrained apps anymore), and
enterprise software infrastructure is written in a wide range of languages
ranging from C, through Java to even Python. What C++ is mostly used for are
games and desktop GUIs... :D

~~~
cageface
_What C++ is mostly used for are games and desktop GUIs..._

Hardly. Just about every interesting native application is written in C++.
Chrome, Photoshop, Cubase, Ableton Live, AutoCad, Java, V8, any AAA video
game, etc.

Whether you like C++ or not the fact remains that if you want to write an
application of any complexity that really pushes the hardware it's just about
your only reasonable choice. Maybe people still write kernels in C but kernels
really aren't that complex compared to the applications they run.

~~~
pkolaczk
You listed mostly desktop apps and games = exactly what I said. And even in
this area, C++ is not used exclusively - see Minecraft (Java), Azureus (Java),
Gimp (C), VisualStudio (new code mostly C#). So no, not _every_.

BTW: There are many interesting and successful complex applications really
pushing the hardware that were not written in C++: Cassandra (Java), Hadoop
(Java), PostgreSQL (C), Netty (Java), Nginx (C), TeX/LaTeX (uh, this one is
really interesting). So, again, C++ is not the only reasonable choice when
performance matters.

~~~
cageface
Scaling across multiple machines is a completely different problem than
pushing a single machine to the limit, with completely different constraints.
Once you move beyond a single CPU and you can tolerate higher latency then
languages like Java start to become more viable.

When you need maximum performance and minimal latency from a single machine
C++ is still the first choice and the number of high-performance apps written
in C++ vastly outnumbers those written in C. Check high frequency trading for
another example.

~~~
pkolaczk
There are companies doing HFT with reatlime Java and custom hardware. Sure,
C++ has its place there, too, but again: not the only viable option.

------
z3phyr
There are languages specially groomed to replace C++, like D and Rust, but
they might never; Not in this decade.

The day LLVM gets rewritten in Rust, that day Rust barely starts replacing
C++.....

------
stephen_g
I know what he means about teaching - I do a lot of systems (embedded) stuff,
and love (well written) C++, but the course I did on it at Uni was awful. If
that had been my only exposure to C++, I never would have wanted to touch it
again!

