W
White Wolf
sfuerst said:Hello, I've written an article at http://locklessinc.com/articles/10_problems_with_c++/ [SNIP]
Any comments, or flames are welcome.
Your captcha at the web does not work, so I have to put here my comment:
I may sound critical, but it is just my inability to talk properly. I
can understand why you wanted to share your thoughts and I understand
that you have placed a great deal of concern and work into this article.
However, it is full of bull byproduct. It shows clearly that there
is a lot you don't know about C++. You have serious misunderstandings.
I don't know if the blame falls on bad teachers or bad books, or what,
but your misconceptions and misunderstandings run deep and seem to be
fundamental. They remind of some colleagues from a decade ago, who have
learnt C++ from a Java guy; so all they knew about C++ were
misconceptions and a fundamental hate and distrust towards the language.
Fixing your language knowledge issue is simple. Get a good book. I
suggest Bjarne's new book.
But there is another problem. And that is an attitude problem. You
make wild assumptions and then you act on them as if they were true,
without checking their validity. That is a very dangerous, I would say
suicidal way of working for a programmer. I have seen one software that
was 2 times slower because the head architect assumed that dynamic
memory allocation is expensive and he has forced people to statically
allocate all memory. He did not check his assumptions. And they were
wrong.
So my suggestion to you is to be aware of your assumptions and check
them before you act on them. I have only looked at the first 3 points,
because I saw a pattern and frankly I have decided that if the quality
of your arguments is the same as in the first 3 point, I don't want to
frustrate myself with reading the rest. But even in those first 3
points you will see the examples where you have had a wrong assumption
and instead of checking if the assumption is correct, or asking for
advice on USENET about your way of thinking, you have acted upon your
assumptions. Why is that bad? Well, for one, posting the link to this
article on the USENET triggered two things:
1.) Experienced people are frustrated, concerned or laugh about your
article. Some, like I, may even go into damage control mode, because of
reason 2
2.) Unexperienced people won't be able to see that your assumptions are
wrong, because you state your wrong assumptions as facts. So they will
accept what you say. And that will cause them harm, because later in
life they will have to spend serious time and effort to unlearn all the
bad things they have read here.
*** The complaints in item #1 are based on 3 serious misconceptions and
some more:
1.) operator new cannot be replaced. It can. See your favorite C++
textbook.
2.) The new operator combines 2 operations: allocation and
initialization. Clearly a misconception. The new operator *only*
allocates memory. It does not combine anything else. Constructors do
the initialization.
3.) Array allocation is inefficient. It is not. It is more efficient
than any hand crafted code any of us could ever write.
Your problem seems to be here that you want to work in C++ as you would
work in C or assembler. There is no need for you to fiddle around with
allocating arrays and with placement new. Use a vector and initialize
it from a pair of input iterators. You get the most effective code
possible.
*** The complaints in item #2 are based on 2 serious misconceptions and
some more:
1.) Exceptions are means to decouple the site of error detection and
error handling. They have nothing to do with goto. They are not jumps.
They are based on sound principles that does not break or even bend
the rules of structuring programming.
2.) Exceptions have not been created because constructors cannot return
values. Serious misconception. They had to be added into the language,
because of it. But the motivation for the design and existence of
exceptions has nothing to do with constructors. It has to do with the
desire to make errors harder to hide (error codes can be ignored without
consequences); the need to make code between the detection site and the
handling site be "untouched" by the fact that an error may occur
(error/return codes have to be delegated by all functions on the call
stack); and the needs to fully separate the detecting code and the handler.
Your example with the class with the crazy error code reference argument
is as bad as it could be. If your constructor exists normally, while
not creating the object properly, you are living in
undefined-behavior-land. You have a variable with the type
Transmogrifier, but it is *not* a transmogrifier! You ignore the error
code, or you do not return from your function or exit the block where
the variable is living... anyone later may start using that object as if
it were properly constructed. The compilers won't and cannot stop you
from doing it (in any language I know). But that object is not
constructed properly, so your code will do stupid things.
*** The complaints in item #3 are based on at least one serious
misconception:
You think that compilers are dumb. That they will do 2 additions when
one suffices. They don't. That extra addition is removed at compile
time. If a compiler is requested to access an element of an object (any
element) it will use a compound access with a base register and an
offset. ALWAYS. Compilers are not stupid. The expression to access an
element in case of multiple inheritance is something like this:
address[base_adjustment+element_offset]
where both base_adjustment and element_offset are compile time
constants! So in the final binary/machine code you will see:
address[base_adjusted_element_offset]
No speed loss whatsoever.
BR, WW