variables vs references

T

Tom Payne

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?
 
A

Alf P. Steinbach /Usenet

* 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...

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.

So, in order to be able to reason about validity of programs, one must also
consider that references are sort of secondary.

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. 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
 
G

gwowen

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?

Visibly, thats true. But when your function returns a reference, the
"return" statement must be thought of as "return_a_reference_to".
 
F

Fred Zwarts

Tom Payne said:
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?

int n = 3;
int &k = n;

Visibly a referece k is initialized with an integer n.
But is does not mean that a reference is an integer.
The same thing happens in the "return n;" statement.
 
S

SG

Consider the code:

  int n = 3;
  int& g() { return n; }

Visibly g() return a reference to an integer, and g() returns n.

More specifically, g returns a reference to the int object n refers
to.
Does it not follow that n is a reference to an integer?

It's not a reference in the C++ language sense. But n also refers to
an int object, yes. Maybe "lvalue" is the term you're looking for. n
and g() are both lvalue expressions. As such, they refer to some
object in memory (or a function). In this case, both expressions refer
to the same int object.
 
T

Tom Payne

Alf P. Steinbach /Usenet said:
* Tom Payne, on 12.11.2010 07:02:

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,145
Messages
2,570,824
Members
47,369
Latest member
FTMZ

Latest Threads

Top