S
Steven T. Hatton
Steven said:(e-mail address removed) wrote: [snip]For convenience, let's use the term 'cause' to denote the
statement or expression that results in undefined behavior
'effect' to denote the undefined behavior itself.
So let's consider an example involving references:
int func(int& r)
{
return r;
}
int main()
{
int* p = 0;
return func(*p);
}
Now we both agree that the 'cause' of the undefined behavior
is the expression *p in main. The 'effect' could be anything
at any time, but let's suppose that in this case, it is a
"seg fault" during the execution of func.
You seem to think that the fact that the effect occurred in
func is somehow an indictment of func -- specifically of the
fact that it takes a reference parameter.
No. It is just a counterexample presented to demonstrate that the
compiler will not prevent you from attempting to pass a dereferenced null
pointer to func().
Sure, a compiler will not usually prevent you from causing undefined
behavior. However, the use references did not cause or contribute to
the undefined behavior.
Had that occurred in a program that otherwise used pointers, one might argue
that the anomalous use of a reference /did/ constribute to the problem.
If your point is that reference parameters are not a silver bullet
that make undefined behavior a thing of the past, then I agree.
They can help to some degree insofar as they help one reduce the
use of pointers generally.
I guess if there is a situation inwhich references are useful as parameters,
then perhaps they should be used. I haven't encountered a lot of
situations like that. Usually my function calls change the state of the
object of which the function is a member. If there are parameters, they
are typically pretty lightweight and usually not modified by the call.
The purpose of the standard is to specify what a "well-defined program"
is so this isn't much of a caveat. Once you start invoking undefined
behavior your program is no longer a C++ program as defined by the
standard.
There is a significant difference between what is forbidden and what is left
undefined. As I understand things, code that results in undefined behavior
is not an error, and the compiler is not obligated to warn you about it,
and should probably not produce an error when it encounters such code.
IOW, you're on your own.
I don't deny there are many cases where pointers are the best choice.
However, it's hard to imagine a program that doesn't (also) have, say,
local variables.
Most of the data is stored in containers which are typically operated on by
member functions of the class that owns the container.
If you want to talk about what happens *after* you invoke undefined
behavior then we're no longer talking about C++. In C++ there is no
such thing as a null reference.
My guess is, the reality of what happens is that the result of dereferencing
a null pointer /is/ used to initialize the parameter, and that's where the
segfault comes from. The Standard does not stipulate that this is an
error.
References don't preclude polymorphism.
That is correct. I was thinking too narrowly.
Refererences don't preclude polymorphism.
What I should have said is that you are not using polymorphism the way it is
used in a scenegraph. Which is really more RTTI than polymorphism.
Also, who said anything about "programming by exception"? If there
is a pointer to be dereferenced, then whoever does the dereferencing
is responsible for "knowing" that the pointer is not null -- either
by a runtime check or by understanding the invariants at that point.
I was thinking in terms of the flow control in a scene graph where it is
quite common to use a dynamic_cast in an if() condition.
Again, references don't preclude polymorphism. I'll accept that the
design domain is a factor in how many pointers one uses.
The comment about abstract interfaces was regarding the use of indirection
to hide the implementation. I believe that's called a pimpl or something
like that. I was also thinking about Apache's C++ DOM binding
recommendation:
http://xml.apache.org/xerces-c/ApacheDOMC++BindingL3.html
Ironically Qt uses references in most places where Apache uses pointers.
http://doc.trolltech.com/4.0/xml-tools.html
I went from using Xerces-J to Xerces-C++ to QtXml. That was the first time
I had encountered references and was quite confused.