views:

178

answers:

2

In Beyond Java(Section 2.2.9), Brute Tate claims that "typing model" is one of the problems of C++. What does that mean?

A: 

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.

cdiggins
Your points are well taken. But C++ is superior to C because of its strict static typing system. What you are talking about is the auto conversion between types (which unfortunately was inherited from C). Also Note: Conversion between two different enum is not valid (though unfortunately it does auto convert to int).
Martin York
+3  A: 

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 Dogs and Cats! 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

  1. C++ mostly contains C as a subset (the differences are usually too minor to list).
  2. C++ includes reinterpret_cast<T> specifically to allow hacks like this.
  3. 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.

pavpanchekha
You have show why C is not strictly typed not C++. The cast you use is a C cast a though it is usable from C++ it is still considered a C construct and it use is discouraged in preference to the C++ cast.
Martin York
This is a feature of C++ not detrimental. Admittedly it is open to abuse but it does not make it harder to write robust or secure software. Because of C++ strict static typing pointers are usually not random pointers (they may be because of abuse of reinterpret_cast<> or inexperienced programmers using C cast as above, but in good code that does not happen).
Martin York
Java (sun's impl) does have pointers. See javadocs on sun.misc.Unsafe. Specifically getAddress(long address) and putAddress(long address, long x). Yes you have to use reflection to access Unsafe, and yes it isn't portable, but we are talking about intentional abuse here right?
KitsuneYMG
Err, no abuse of C pointers is possible either. What you're doing is undefined behavior. It is no longer a C program. A C program is described by the C standard. Undefined behavior is not. If you don't respect the rules of the language, then yes, you can write some pure nonsense. But that's not because of any flaws in the language. It's because you didn't *know* the language you're using.
jalf
Not at all true. First of all, given that all compilers do the same thing when such abuse happens, you can hardly consider it undefined. Consider HTML, for example. The effects of invalid markup are undefined, but invalid markup nonetheless happens. And it mostly works anyway.Furthermore, the existence of `void*` pointers is part of the standard, and they are used in the standard library (well, the standard C library, but that's available in C++).The kernel of the matter is that in JAVA (and just about all modern languages), an `int` is an int, where in C++, an int is a bit pattern.
pavpanchekha