> > C++ is an exteremely 'complicated' if you need efficiency. Whereas
> > C has a reasonably constant number of assemby instructions per
> > C instruction (I think it averages around 5), C++ has a greatly
> > varying number of assembler statements per C++ statement, it may
> > be more than 500! (If you consider for instance an 'elegant'
> > construction
With optimizing compilers - this is a non-issue, and just like a C programmer
knows a division operation is much more expensive than an addition, a C++
programmer knows a temporary construction and "implicit" copy constructions
are more expensive than other alternatives.
I doubt the highest optimization level in a typical C compiler will generate
a "reasonably constant number of assembly instructions per C instruction",
and on CISCs such as Intel, this number would be meaningless anyhow.
Some operations are expensive, this should be known to the programmer, in
both C and C++, when calling expensive functions, or in C++: when invoking
expensive language operations. Almost all interesting work in C is done via
function-calling anyhow, so you shouldn't compare the primitives of the one
language with the other, but rather the whole thing. To a C++ programmer,
the explicitness of the cost of copy-construction is as explicit as the cost
of calling any expensive function.
C++ has very little implicitness added to C, most of it is actually pretty
good:
A) Object copy construction when passing as parameter or a return value (hard
to say it is very implicit though, because one explicitly chooses to pass by
value, and thus copy-construct).
B) Automatic destruction: This is probably a good thing, at least if
destruction is used properly - for cleanup of resources. And sometimes for
the nice 'scoping trick' (of using a construction/destruction to act upon an
entrance/exiting of a scope, for a lot of easy debugging information, very
safe scope-bounded locks, etc.)
C) Indirection level of function call: Virtual functions calling syntax is
the same, although it may be one indirection/pointer-level more expensive.
This is a Good Thing (TM) as the addition is not very expensive, and quite
explicit on the defining side (except for the lack of need to re-specify it
in deriving methods).
D) Unexpected flow of code when not specifying the throw(): Probably a very
good thing, that allows 100% error handling, that never forgets to handle an
error, and easily classifies errors and encompasses their treatment code in
the right places. If you want, you can always specify exactly what you throw
and make the flow of code quite explicit.
E) member-scoping: (no need to specify this->) Yes, I agree this is a
seriously problematic feature, which is definitely evil, and I myself had
encountered quite a few bugs over it (Accessing the wrong variable).
> I agree completely with all of this. I also hate the implicit
> member usage scoping. If you want to use a field or member function,
> you should have to explicitly use the entire hierachy right from
> the this-> pointer.
I agree
> The words 'implicit', 'elegant', 'suggested',
> and other ambiguities do NOT belong in a spec for a real-world
> product. All you end up with are bug potentials, opacity, obscurity,
> incompatibilities, etc.
With most implicit things, such as implicit side-effects, and 'suggested'
things that are used to affect what really happens, you're probably right.
When it comes to abstracting more from the programmer (such as virtual
function calls, or allowing temporarily construction of objects to
type-safely send information between functions, or handling errors separately
allowing return codes to be used properly) is bug-eliminating, and reduces
the complexity of the code, allowing the programmer to deal with real bugs.
Also consider automatic memory management, which is known to reduce the
number of bugs significantly, even though it adds implicitness and
abstraction.
> Use of C++ code as a callback from C - yep there's lots of C out there,
> implementation of the this-> pointer, #ifdef nastiness to get rid of the
> this pointer, implementation dependence of the this pointer passing between
> compilers... just some more of my pet peaves about the langauge.
The lack of binary standards is surely a C++ problem. ORB's, and COM seem to
address this problem. Problem is, COM is Windows-specific and noone uses
CORBA/etc.
> There are other dimensions of C++ that are just plain broken,
> due to fsck-ups in the spec. I don't even want to revisit them
> in my mind. Wish I had written them up into a doc first, but my urge
> to throw my notes into the garbarge was too great and too satisfying...
Yes, most of them are actually derived from C :) Lack of array safety is a
major one. void*, the mere concept of casting (which should be represented
as construction-of, and not as casting), and other type-hellish C things are
other major problems.
Most of the things that bother me are actually its lack of abstraction and
OVER-explicitness, such as having the redundancy of having both indentation
and {} markers, which after using Python for a while, feels really stupid
(There are serious problems that can result from loss of synchronization
between the two representations, and it allows misleading code).
Static typing has many merits, but from experience it is usually
counter-productive, although makes optimizing easier (although in theory it
should not be more optimized).
Virtual functions are not the default, also increasing some unwanted
explicitness.
The annoying redundancy of declaration and definition of things that can
known automatically.
Another note:
Soon optimization is a serious problem many C programmers have. They
optimize the code on a local-level, and put time and effort into it, when
writing the code, rather than writing it quickly, reliably and safely,
optimizing the algorithmic levels, and only when profiling information is
available, optimize the local-level code.
Local-level optimizations lead to more confusing code, that tends to have
more bugs and make more implicit assumptions. And for what? To save a few
cycles once in a few seconds? Only optimize where it matters.
Eyal