Re: variables vs references
Alf P. Steinbach /Usenet <alf.p.steinbach+usenet@gmail.com> wrote:
* Tom Payne, on 12.11.2010 07:02:
Consider the code:
int n = 3;
int& g() { return n; }
Visibly g() return a reference to an integer, and g() returns n. Does
it not follow that n is a reference to an integer?
As far as C++ is concerned there's no way to differentiate a reference to 'n'
from 'n' itself.
So technically, at the level of observable effects, disregarding insights that
may be gleaned from timing the execution or inspecting the machine code or such,
yes. This also follows from the view of C++ references as simple aliases. It's a
view that holds for valid programs...
I a bit suspicious of the "alias" view because int& g() { return *new
int; } returns a newly created integer-valued object that has no names
and no aliases.
However, conceptually we think in terms of original object and external
references to it. And that's also what the compiler has to do. And when you have
an invalid program, one that e.g. produces a dangling references (such as a
function returning a reference to non-static local variable), then the
equivalence between references and the objects that they refer to, breaks down.
IMHO, dangling references are somewhat akin to floating point
representations that are not a number, we don't speak of the
representation as a distinct entity. We don't say that we returned an
IEEE754 of the square root of two. Sure, when we return n, we return
the address of n, but I don't think that address deserves to be called
"a reference." It exists only at the implementation level, just like
the IEEE754 represenations of floats.
So, in order to be able to reason about validity of programs, one must also
consider that references are sort of secondary.
I'm hoping to escape that, but I'm not yet confident I've succeeded. ;-)
It is a common problem in teaching and learning programming, that the same term,
referring to essentially the same thing, still can mean subtly different things
depending on the context that is assumed in one's head (e.g. here, am I talking
about valid C++ programs, or am I considering validity, or am I thinking about
how it's translated to machine code, or what). And often, in discussions, such
context is just assumed, implicitly.
That's what I'm trying to do in this case, i.e., teach intermediate
C++ to CS majors in a way that will harmonize with what they'll learn
in their principles of programming languages courses. What I hope can work
is the view that:
The declaration "widget x;" says, not that x is a widget, but that x
is a reference to a widget, also known as a widget-valued object in
cases where widget is not a reference type.
In the case I gave above, the declaration of n would make it a
reference to an integer, namely 3, and the declaration of g() says
that it returns something of type int&, namely n. So the pieces seem
to fit in that case.
So, then
int& r = n;
declares that r refers to an int& namely n, which also seems to work
since by the above principle n is indeed an int&.
I realize that's not the way that the C++ community usually talks
about these things, but it seems to work well. But I fear that I
may be missing something.
I think the worst example I've experienced
was a person who steadfastly maintained that it was meaningless to talk about
"the current thread". Notwithstanding that the API being discussed had a
function GetCurrentThread. It turned out to be impossible to convince that
person that a meaningful interpretation could exist, and I gave up when the
percentage of innuendo and ad hominem reached 99%.
Cheers & hth.,
- Alf
These kinds of discussions can quickly reach the theological level.
Thanks,
Tom