2009/9/8 Mason Wheeler :
Your assertion that most initialization values should be zero or NULL
is completely f’n retarded. It is critical to initialize values
yourself.
This is true, you should be initializing variables yourself, but
having a sensible default assigned by the constructors of the various
types you’re working with helps. Not zeroing everything through some
backend compiler magic, but using well designed type classes that do
it for you. Even int and double have constructors, which do assign a
zero value by default. The compiler just doesn’t always call these
constructors on basic types when you might expect it to.
To make it extra clear for those who don’t get it: ?Zero is often not the
right ultimate value to initialize your references to when you create an
object. ?But it’s the only starting point that makes sense, because
things can go wrong while creating an object, and C++'s object model
not zeroing object memory before the constructor runs is a serious
defect.
On the other hand, there’s often a fair amount of the object that you want
to initialize to 0, especially non-object members. ?In this case, zeroing
the memory beforehand saves you a lot of work.
“Zeroing memory beforehand” would also be time consuming for large
types and arrays. So would calling constructors. Also, if you’re
using pointers, the compiler can’t really initialize the pointer’s
target, only the pointer itself.
The reason you need RAII when you don’t zero out the memory is because
if something goes wrong during object construction and you throw an
exception, the destructor has no way of telling how far along the
construction process got before bailing out, so it doesn’t know which
sub-objects are safe to destroy and which aren’t. ?If the memory had been
zeroed out first, you could call Free on everything safely.
You’re not likely to get an exception when assigning values to basic
types. You could initialize the simple stuff at the beginning of the
constructor and the more complex stuff near the end. Also, don’t
forget that most exceptions can be caught. You can put a try/catch
block in a constructor. You can also set a flag at the beginning of
the constructor and clear it at the end to indicate whether it
finished or not.
Sure, in Imagination Land where most of the Resources you’re Acquiring
only exist inside in-process memory, and aren’t things that exist in
other processes, in the kernel, on other systems, or in meatspace (try
telling the engineers that write systems at a nuclear power facility
they can’t use RAII because all their plutonium should have been
initialized to zeros.)
If a value exists “in meatspace” then you need some sort of user input
function to get it into the computer. I would rather avoid calling
such a function from a constructor, and rather pass the value as a
constructor argument or fetch it after the object is created.
Umm… most of the resources you acquire do exist only inside process
memory! ?Show me even one program where external resources account
for more than 1% of resource acquisitions. ?And there are plenty of
better ways to handle external resources. (And if you know of a nuclear
power plant whose control system runs on C++, please let me know
where it is so I can make sure I don’t live nearby.)
Anything which uses files, input devices or system calls.
I’d be more worried about nuclear power plant software that tries to
use an uninitialized value, no matter what the language. I kinda
expect at least a few would run on Fortran and Cobol; is that an
improvement?
Bottom line: You can say “I like feature X” or “most of the people using
this language like feature X”, but, as you pointed out, that’s a real
subjective measurement. ?A much better way to measure the quality of
a language feature is to see what else uses it. ?Truly good features get
copied around and integrated elsewhere. ?AFAIK the only other
programming language that implements RAII is D. ?No surprise there,
since its object model is heavily based on C++'s, and it allows you to
allocate objects on the stack.
If you don’t like a particular programming language, use a different
one. Most compilers / interpreters allow you to call code written in
other languages, so “but library x is written in y” isn’t really an
excuse.