Anybody who calls C, C++, and Java three of the most different programming languages out there is someone who has never tried LISP, Prolog, or SQL.
He also flat says "C++ OOP has nothing to do with Java-like OOP", which is just not true. To name two big, major things, Liskov substitution and class invariants both work the same way when modeling Java and C++ code.
He also has some strange beliefs about the total supremacy of the compiler when it comes to writing Assembly. Compilers are great tools (as my buddy Doug says, "a compiler is an expert system for creating Assembly"), but like all expert systems they've got holes in their game. In the long run the compiler will eat your lunch, but in the small run the human can still prevail. I've written Assembly that out-performs compiled code for ~100 lines; I know several others who have done likewise.
The author seems to have a lot of technical understanding of the C++ language, but not very much in the way of wisdom about it.
Calling C, C++ and Java "the most different programming languages in the world" is, of course, an exaggeration, but it's hard to disagree that the way you write idiomatic code in the three language is completely different.
As an observation, that's trivial: as an apologia, it's inadequate.
I'm judging the author on what he said, not what other people think he really meant to say. If you change what the author said to be "C, C++ and Java are written in different ways," then sure, the author's right. But that's not what the author wrote, and what the author wrote is unsupportable.
I think you are nitpicking here. There is a figure of speech called "hyperbole" which "the use of exaggeration as a rhetorical device" (http://en.wikipedia.org/wiki/Hyperbole).
BTW I don't understand why you refuse to comment on the original post. The author could clarify to you what exactly he meant.
> [...] most of them think that objects live elsewhere and should be referenced. So they usually do the horrible Class* ptr = new Class(); pattern by default [...]
> The point is that they don’t understand C++ object model. Objects live on the stack except explicitly stated.
So, why did managed language designers decide to use heap allocation for reference type objects?
About that vector2d class: it took me some time to get it, but now I can't unsee that memory leak going on there.
If that's straight-up bog-standard ANSI C++, then yes, there's a memory leak.
But, to put my Devil's Advocate hat on a moment: the environment could be GCed and new could be overridden to return a GCed pointer, as opposed to a naked pointer. (There are lots of good GCs for C++ -- see, e.g., http://www.hboehm.info/gc/)
One of the great things about C++ is how thoroughly you can customize the system using operator overloading. One of the big drawbacks about C++ is that without knowing the precise environment in which the code is operating, you really don't know what 'new' does. Or any other operator, for that matter. :)
Interesting, but maybe I'm missing something here. If I just want automatic deallocation, why would I use bdwgc instead of using "vanilla" smart pointers from standard C++?
Most of the smartpointers in the modern C++ standard weren't official until TR1 in 2003; even then, a lot of compilers took a long time to catch up. Prior to 2003, the only smartpointer in the C++ standard was std::auto_ptr, which had some really unpleasant semantics.
There were two basic choices: go with a smartpointer library like Boost or Loki, or go with the Boehm-Demers-Weiser GC. The GC route was pretty easy and minimal pain, while Boost and Loki were moving targets. A lot of places went with the more stable BDWGC instead.
In my recollection, smart pointers were a fairly common C++ idiom in the early 1990s. Ref-counted shared_ptr and scoped_ptr were even proposed in 1994 for standardization, but didn't quite make it (scoped_ptr mutated into auto_ptr). There were also cow, deep-copying, intrusive, and ref-linked smart pointers. It was easy to write your own smart pointer, while GC was something alien and magic.
> So, why did managed language designers decide to use heap allocation for reference type objects?
Because you avoid having to think about where to put the object while also not eating the cost of copying it if you guess wrong.
The lifetime of a heap object is whatever you define the lifetime to be (which thanks to GC is very flexible) the lifetime of a stack object has an absolute maximum.
10 comments
[ 8.3 ms ] story [ 40.1 ms ] threadHe also flat says "C++ OOP has nothing to do with Java-like OOP", which is just not true. To name two big, major things, Liskov substitution and class invariants both work the same way when modeling Java and C++ code.
He also has some strange beliefs about the total supremacy of the compiler when it comes to writing Assembly. Compilers are great tools (as my buddy Doug says, "a compiler is an expert system for creating Assembly"), but like all expert systems they've got holes in their game. In the long run the compiler will eat your lunch, but in the small run the human can still prevail. I've written Assembly that out-performs compiled code for ~100 lines; I know several others who have done likewise.
The author seems to have a lot of technical understanding of the C++ language, but not very much in the way of wisdom about it.
I'm judging the author on what he said, not what other people think he really meant to say. If you change what the author said to be "C, C++ and Java are written in different ways," then sure, the author's right. But that's not what the author wrote, and what the author wrote is unsupportable.
BTW I don't understand why you refuse to comment on the original post. The author could clarify to you what exactly he meant.
> The point is that they don’t understand C++ object model. Objects live on the stack except explicitly stated.
So, why did managed language designers decide to use heap allocation for reference type objects?
About that vector2d class: it took me some time to get it, but now I can't unsee that memory leak going on there.
But, to put my Devil's Advocate hat on a moment: the environment could be GCed and new could be overridden to return a GCed pointer, as opposed to a naked pointer. (There are lots of good GCs for C++ -- see, e.g., http://www.hboehm.info/gc/)
One of the great things about C++ is how thoroughly you can customize the system using operator overloading. One of the big drawbacks about C++ is that without knowing the precise environment in which the code is operating, you really don't know what 'new' does. Or any other operator, for that matter. :)
Most of the smartpointers in the modern C++ standard weren't official until TR1 in 2003; even then, a lot of compilers took a long time to catch up. Prior to 2003, the only smartpointer in the C++ standard was std::auto_ptr, which had some really unpleasant semantics.
There were two basic choices: go with a smartpointer library like Boost or Loki, or go with the Boehm-Demers-Weiser GC. The GC route was pretty easy and minimal pain, while Boost and Loki were moving targets. A lot of places went with the more stable BDWGC instead.
Because you avoid having to think about where to put the object while also not eating the cost of copying it if you guess wrong.
The lifetime of a heap object is whatever you define the lifetime to be (which thanks to GC is very flexible) the lifetime of a stack object has an absolute maximum.