Op 25-Feb-13 8:03, Juha Nieminen schreef:
Whenever someone has the idea of making a "better, light-weight C++",
what results is a language that produces less efficient and more memory
consuming executables, and which is a lot more rigid from the programmer's
point of view.
In case of Java that is true, but there are other less fascistic
languages that don't insist on putting the application programmer in a
straight-jacket.
I don't really see Java (or C# for that matter) as a "better,
light-weight C++", but rather as programming languages with a different
goal and scope in mind. The closest thing that seems to be intended as a
"better, light-weight C++" is the D programming language. I'm curious
how you feel about that language.
This is the invariable result because such people always
think that:
1) Handling objects by value is way too problematic (because it makes
things like automatic garbage collection a lot more difficult, breaks
pure OO because not all objects may be dynamically bound, etc.) which
means that classes must only be instantiable dynamically and handled
through references.
Both Java and C# can have objects on the stack. In case of Java only
primitive types (such as int), in case of C# also user defined types
(struct) can be placed on the stack. So I don't believe that GC implies
that "handling objects by value is way too problematic". It is more of
language design choice/philosophy; does the language designer feel that
he should decide what is "good" for the programmer, or does the language
designer trust the judgment and intellect of the programmer.
Given how slow the standard libc allocator is, this
means that creating objects will be at least 10 times slower than how
it is when in C++ you instantiate them on the stack or as an array.
They also consume more RAM (because the memory allocator always needs
to allocate extra memory for its bookkeeping data.)
GC language implementations that use a generational collection scheme
(such as Java and C#) don't use libc for dynamic allocations; the new
statement with these implementations has much lower overhead that the
typical C++ new implementation. Basically the only thing that needs to
be done is to check if sufficient space is available in the current
generation and if so increment a pointer. See also:
http://www.ibm.com/developerworks/java/library/j-jtp09275/index.html
2) Classes must always be dynamically bound, because that's OO, and it
makes the behavior of classes more consistent (and because of point #1
above, it's now possible to enforce that.) That's certainly true, but
it also means that all objects are now larger by at least the size of
a pointer, no matter how simple and small they would otherwise be, and
even if no dynamic binding is used in them at all. It also makes compiler
optimizations more difficult because the compiler cannot now inline any
member functions because it cannot know if they are actually dynamically
bound.
Not always. In Java every method is virtual (except static, and you can
mark a method as final), in C# it is the same as C++; methods aren't
virtual unless you tell it is virtual. Also JIT compilers have been
known to do rather clever tricks to inline virtual methods.
3) They have been taught through FUD that multiple inheritance is
eeeeeevil and scary, and therefore it must not be supported. Therefore
they will implement a crippled version of multiple inheritance (which
they will call "interfaces"), while still denying the fact that the
language *does* support multiple inheritance (just a crippled version
of it.) This forces code repetition from the programmer's part in many
cases, making the language more rigid.
I understand that the main reason not to add support for it in Java that
the language designers found it too hard to implement.
4) Likewise they have been taught through FUD that C++ templates are
eeeeeevil and scary, and therefore they must not be supported. Therefore
they will implement a crippled version of templates (which they will call
"generics"), while still denying the fact that the language has templates
(just a crippled version of them.) No vectors of ints or anything like
that supported, for no obvious or rational reason (other than that C++
templates are "evil".) This makes the language more rigid and less
efficient.
Though C++ templates are extremely powerful, if you go beyond containers
of type T I cannot say they are the most intuitive feature of C++ or
well understood by the average C++ programmer. I guess generics fulfill
80% of the need, at significantly less than 20% of the language
complexity. I can imagine why a language designer makes such a trade-off
(even though I do sometimes miss the power C++ templates when
programming in a language other than C++).
If you want a concrete example of a popular "C with OO" which some people
consider "better than C++", try Objective-C. It consumes more memory and
everything related to classes is slower than in C++. (According to my
measurements calling a member function is approximately 6 times slower
than calling a virtual function in C++. While it's impressive that they
have succeeded in making the calls that fast, considering that they use
messaging, each member function call is still 6 times slower.) Of course
there is no MI nor templates, and the classes themselves have multitude
of problems (such as no constructors nor destructors, other than by
naming convention and manually having to call them.)
After reading this rant I got the impression that it is based on Java
experience from well over a decade ago.
I learned C++ 20 years ago, and used it for at least 90% of the projects
I have done in my career. On occasion I use other languages like Java,
C#, Python or whatever language appears to be the most suitable choice
for the problem at hand. C++ is almost always at least a reasonable
choice, but certainly not always the best choice.
When I hear Java fanboys ranting about C++, it is often quite clear they
are rather ignorant as far as (modern) C++ is concerned. Likewise when
C++ fanboys start whining about this language does not support
this-or-that C++ feature so it must suck. The big mistake many people
make is trying to treat the other language as the language they know
best, rather using the idioms and conventions typical for the language.
A language feature cannot be considered in isolation, you have to look
at the bigger picture. In C++ I use RAII a lot, and in my opinion the
language would be pretty useless without it (when using exceptions). And
though I miss RAII in other languages, I don't miss it as much as one
could expect due to things like garbage collection and finally, using
and lock statements. Python doesn't support templates, but then again
duck typing pretty much eliminates the need. In Java and C# you have
reflection, which can be quite useful on occasion, but C++ doesn't have
anything that come close to that...etc.
As far as performance is concerned, C++ gives you the most control, and
if you need that control C++ is the way to go. But many times
performance is not that critical, good enough is good enough and other
considerations are more important. My experience with languages like C#
are in real life not that much slower for most tasks (except for startup
time). Quite often the speed of an application is more limited by I/O
than by raw processing speed.