0xBADFEED: your points on legacy code from the pre-smart pointer era and on stack overflows convinced me. I don't agree to everything you said, though.
Since the introduction of decent smart pointers there is no reason to consider "raw" pointers the default, as the techniques are equally accessible to the developer. Using smart pointers doesn't require any more effort from the programmer than using raw ones (in fact, smart pointers require less thinking and less typing). Also, there is nothing about C++ that pushes programmers to use raw pointers rather than smart pointers, and in fact most programmers in the C++ community are now encouraging each other to use the smart ones. Which of the techniques is the default mostly depends on the culture, and the culture has been heading towards smart pointers at least since 2003. The transition isn't over yet, but soon we will consider raw pointers a "special case" which you only use for systems programming.
And yes, the mainstream smart pointer implementations assume that you don't fiddle with the underlying raw pointer. Therefore they don't check for null pointers. I think that doesn't pose much of a problem for safety, because if you're fiddling with the underlying raw pointer you're pretty much causing the problems on purpose.
Code: Select all
//using a smart pointer as they're always taught to be used
shared_ptr<int> our_pointer = new int; // no way to retrieve the underlying
// raw pointer
// ... do something with it
} // our freestore int is automatically deleted, guaranteed without problems
// using both mechanisms on purpose to defeat the purpose of smart pointers
int *raw_pointer = new int; // first save the raw pointer value so you can
// access it later
shared_ptr<int> our_pointer = raw_pointer; // the shared_ptr doesn't know of the
delete raw_pointer; // mess with the raw pointer which you shouldn't have in the
// first place
raw_pointer = 0; // mess more with the raw pointer
shared_ptr<int> their_pointer = raw_pointer; // again deception of a smart pointer
int x = *their_pointer; // ouch! null pointer
} // armageddon (deletion of dangling our_pointer)
But again, I must admit that you're right about the old legacy code issue and that does make such uses of C++ inherently less safe than Java. Same for stack overflows. So I guess that's a point for Java.
Conclusions of the arguments so far (still open for discussion of course):
- C and C++ are faster and much more memory-efficient than Java.
- C++ is more flexible than C and Java.
- There is no real difference in the ease of debugging between C++ and Java (though they are probably both easier than C because of higher modularity).
- Java is safer than C++ and C++ is safer than C.
Although Java is still not the safest language around, it might be the case that there is no other language that is both at least as fast and at least as safe; and that's enough for Java to be a valuable addition to the spectrum (I think). If we don't consider Groovy, at least.