In Beyond Java(Section 2.2.9), Brute Tate claims that "typing model" is one of the problems of C++. What does that mean?
That it is hard to type C++ code. :-p
Seriously though, they are probably referring to the fact that C++ has a weak static type system, that can be easily circumvented. Some examples: typedefs are not real types, enumerated types are just ints, booleans and integers are equivalent in many cases, and so on.
What he means is that objects in C++ don't intrinsically have types. While you might write
struct Dog {
char* name;
int breed;
};
Dog ralph("Ralph", POODLE);
in truth ralph
doesn't have a type; it's just a bunch of bits, and the CPU doesn't give a damn about the fact that you call that collection of bits a Dog
. For example, the following is valid:
struct Cat {
int color;
char* country_of_origin;
};
Cat ralph_is_that_you = * (Cat*) &ralph;
Watch in wonder as Professor C performs trans-species mutations between Dog
s and Cat
s! The point here is that since ralph
is just a sequence of bits, you can just claim that that sequence of bits is really a Cat
and nothing would go wrong... except that the "Cat
"'s color would be some random large integer, and you better not try to read it's country of origin. The fundamental problems is that while a variable (as in, the name, not the object it represents) has a type, the underlying object does not.
Compare this with JAVA, where not only types, but objects have intrinsic types. This may be due partly to the fact that there are no pointers and thus no access to memory, but the fact nonetheless exists that if you cast a Dog
to an Object
, you can't cast it back down to a Cat
, because the object knows that deep down, it's actually a Dog
, not a Cat
.
The weak typing present in C++ is rather detrimental, because it makes the compiler static type checks nearly useless if you want to truly abuse-proof your application, and also makes secure and robust software hard to write. For example, you need to be very careful whenever you access a "pointer" because it could really be any random bit pattern.
EDIT 1: The comments had very good points, and I'd like to add them here.
kts points out that Sun's JAVA does indeed have pointers if you look deeply enough. Thanks! I hadn't known, and that's rather cool. However, the fundamental point is that JAVA objects are typed and C types aren't. Yes, you can circumvent this, but this is the same as the difference between opt-in and opt-out spam: yes, you could abuse the JAVA pointers, but the default is that no abuse is possible. You'd have to opt in.
martin-york points out that the example I showed is a purely C phenomenon. This is true, but
- C++ mostly contains C as a subset (the differences are usually too minor to list).
- C++ includes
reinterpret_cast<T>
specifically to allow hacks like this. - Just because it's discouraged doesn't mean it isn't pervasive or dangerous. Basically, even if JAVA has opt-in pointers (as I'll call them), the fact is that the person using them has probably thought of the consequences. C's casts are so easy that they're at times done without thinking (To quote Stroustroup, "But the new syntax was made deliberately ugly, because casting is still an ugly and often unsafe operation."). There's also the fact that the work needed to circumvent JAVA's type system is far more than what would make for a clever hack, while circumventing the C type system (and, yes, the C++ type system) is easy enough that I've seen it done just for a minor performance boost.
Anyway, discouraging something doesn't make it not happen. I discourage bad coding, but I haven't seen it get me anywhere...
As for the feature being useful, it admittedly is (just look up "fast inverse square root" on Google or Wikipedia) but it is dangerous enough that, following Stroustroup's maxim that ugly operations should be ugly, the difficulty threshold should be significantly higher.