472,353 Members | 1,672 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,353 software developers and data experts.

Revistiing using return value as reference

I remember there was a thread a while back that was talking about using the
return value of a function as a reference where I had thought the reference
would become invalidated because it was a temporary but it was stated that
it would not. This has come up in an irc channel but I can not find the
original thread, nor can I get any code to work.

Foo& Bar( int Val )
{
return Foo( Val );
}

Will not work, can not convert Foo to Foo&

Foo Bar( int Val )
{
return Foo( Val );
}

int main()
{
Foo& Inst = Bar( 10 );
}

Does not work, same thing, can not convert Foo to Foo&.

Foo& Bar(int Val )
{
Foo Temp( Val );
return Foo( Val );
}

int main()
{
Foo& Inst = Bar( 10 );
}

Does not work, checking the value of Val_ later shows garbage data
indicating the reference has become invalidated (as expected). Can anyone
remember the case where a temp value returned from a function can be used as
a reference and not invalidated immediately?

--
Jim Langston
ta*******@rocketmail.com
Dec 25 '07 #1
68 4164
On 2007-12-25 15:00:36 -0500, "Jim Langston" <ta*******@rocketmail.comsaid:
I remember there was a thread a while back that was talking about using the
return value of a function as a reference where I had thought the reference
would become invalidated because it was a temporary but it was stated that
it would not. This has come up in an irc channel but I can not find the
original thread, nor can I get any code to work.

Foo& Bar( int Val )
{
return Foo( Val );
}

Will not work, can not convert Foo to Foo&

Foo Bar( int Val )
{
return Foo( Val );
}

int main()
{
Foo& Inst = Bar( 10 );
}

Does not work, same thing, can not convert Foo to Foo&.

Foo& Bar(int Val )
{
Foo Temp( Val );
return Foo( Val );
}

int main()
{
Foo& Inst = Bar( 10 );
}

Does not work, checking the value of Val_ later shows garbage data
indicating the reference has become invalidated (as expected). Can anyone
remember the case where a temp value returned from a function can be used as
a reference and not invalidated immediately?
Foo Bar(int x)
{
return Foo(x);
}

int main()
{
const Foo &foo = Bar(10);
return 0;
}

--

-kira

Dec 25 '07 #2
On Dec 25, 3:00 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
Foo& Bar( int Val )
{
return Foo( Val );

}

Will not work, can not convert Foo to Foo&
Should work, but not a very useful thing to do as local copy dies
immediately.

Foo Bar( int Val )
{
return Foo( Val );

}

int main()
{
Foo& Inst = Bar( 10 );

}

Does not work, same thing, can not convert Foo to Foo&.
Should also work. Something else is going on as that syntax is
compiling fine in my compiler.
Foo& Bar(int Val )
{
Foo Temp( Val );
return Foo( Val );

}
I think you meant to return Temp, no? That too should work, but as
with #1, isn't very useful.
int main()
{
Foo& Inst = Bar( 10 );

}

Does not work, checking the value of Val_ later shows garbage data
indicating the reference has become invalidated (as expected). Can anyone
remember the case where a temp value returned from a function can be used as
a reference and not invalidated immediately?
Here's some thoughts:

Foo g_foo;

class Y
{
protected:
Foo _x; // instance (or member) variable
static Foo _y; // class instance variable (i.e., a static)

public:
Foo& GetFoo();
Foo& GetFoo2();
};

Foo&
Y::GetFoo()
{
return _x;
}

Foo&
Y::GetFoo2()
{
static Foo localStaticFoo; // global to all instances of Y but only
accessible within GetFoo2.
return localStaticFoo;
}

int main()
{
Y y;
Foo& foo = y.GetFoo();
Foo& foo2 = y.GetFoo2();
Foo& foo3 = g_foo;
}

A reference has to 'point' to a preexisting instance of something
(i.e., must be initialized to something upon declaration-- note that
this also includes any references that you might have as class members
which must be initted in your constructors' init lists).

In your case where that instance was local, it satisfied your
compiler, but obviously didn't have any use as it was deleted
underneath you when the func exited. So, you have to couple that idea
with a longer living object (such as class member, static member, or
global).

Dec 26 '07 #3
On 2007-12-26 06:01, johanatan wrote:
On Dec 25, 3:00 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
>Foo& Bar( int Val )
{
return Foo( Val );

}

Will not work, can not convert Foo to Foo&

Should work, but not a very useful thing to do as local copy dies
immediately.
Should not work, a reference can not bind to a rvalue.
>Foo Bar( int Val )
{
return Foo( Val );

}

int main()
{
Foo& Inst = Bar( 10 );

}

Does not work, same thing, can not convert Foo to Foo&.

Should also work. Something else is going on as that syntax is
compiling fine in my compiler.
Get a new compiler. Once again, you can not bind a reference to a rvalue.
>Foo& Bar(int Val )
{
Foo Temp( Val );
return Foo( Val );

}

I think you meant to return Temp, no? That too should work, but as
with #1, isn't very useful.
Invoking undefined behaviour I would think.

--
Erik Wikström
Dec 26 '07 #4
"johanatan" <jo*******@gmail.comwrote in message
news:8e**********************************@r60g2000 hsc.googlegroups.com...
What is the danger of binding to an r-value?
If it is possible to bind a reference to an rvalue, then there is no basis
for the compiler to reject:

int x = 0, y = 0;
cin >(x + y);
Dec 27 '07 #5
On Dec 27, 10:16 am, "Andrew Koenig" <a...@acm.orgwrote:
"johanatan" <johana...@gmail.comwrote in message

news:8e**********************************@r60g2000 hsc.googlegroups.com...
What is the danger of binding to an r-value?

If it is possible to bind a reference to an rvalue, then there is no basis
for the compiler to reject:

int x = 0, y = 0;
cin >(x + y);
Hmm... that's interesting. One possible way to deal with that is to
let it put the input into an unnamed variable (which would be
inaccessible unless you expose some sort of global environment a la
python).

If you think that type of programming error is so likely that this
restriction is a net gain, then I guess it's a win. I'm just not
completely convinced yet. :-)

--Jonathan
Dec 27 '07 #6
On 27 Dec, 23:58, Erik Wikström <Erik-wikst...@telia.comwrote:
2. Can you give an example of when it would be useful to bind a
reference to a r-value?
void retransfer(Object& x)
{
x.timestamp=now();
x.transferred=true;
buf b = allocate_superbuffer(sizeof(x));
copy_to_superbuffer(b,x);
}

retransfer (a); //we want to mark Object a as transferred and pass
it along
retransfer (b+c); //we want to pass result of b+c along and do not
care much what happens to temporary variable of Object type the result
of operator+ was assigned to.

Yes, i know. I can easilly write

Object d=b+c;
retransfer(d);

but why? What if i really *don't care* and moreover i *don't want* to
take care of where result of this sum will go? Why should i write one
more line of code (!) if i really don't need it? A man reading my
code would surely be surprised, `Why does he need this d variable??'

Well, one can make more life-bound example, but this one shows that
sometimes we should really sacrifice a hamster for the compiler to get
an elephant past the corner.
Dec 27 '07 #7
Erik Wikström wrote:
2. Can you give an example of when it would be useful to bind a
reference to a r-value?
Consider:

std::vector<intv;
...
v.swap( std::vector<int>() ); // fails
swap( v, std::vector<int>() ); // fails
std::vector<int>().swap( v ); // succeeds

It is especially bad that the middle line fails. The rules of [8.3.5/5] make
it difficult to define swap()-like functions for proxy classes. E.g., it is
somewhat tricky to have a line like

row_swap( A.row(1), A.row(2) );

do a row-swap in a matrix class and be const-correct.
Another surprise caused by the rules of [8.3.5/5] (and frequently coming up
in this group in various disguises) is this:

int main ( void ) {
std::ofstream( "test.001" ) << std::dec << "hello world!" << '\n';
std::ofstream( "test.002" ) << "hello world!" << '\n';
}

On my machine, this creates files like so:

test.001: hello world!
test.002: 0x8048a01

Best

Kai-Uwe Bux
Dec 27 '07 #8
On 2007-12-27 18:19:17 -0500, jk********@gmx.net said:
Erik Wikström wrote:
>2. Can you give an example of when it would be useful to bind a
reference to a r-value?

Consider:

std::vector<intv;
...
v.swap( std::vector<int>() ); // fails
swap( v, std::vector<int>() ); // fails
std::vector<int>().swap( v ); // succeeds

It is especially bad that the middle line fails. The rules of [8.3.5/5] make
it difficult to define swap()-like functions for proxy classes. E.g., it is
somewhat tricky to have a line like

row_swap( A.row(1), A.row(2) );

do a row-swap in a matrix class and be const-correct.
Another surprise caused by the rules of [8.3.5/5] (and frequently coming up
in this group in various disguises) is this:

int main ( void ) {
std::ofstream( "test.001" ) << std::dec << "hello world!" << '\n';
std::ofstream( "test.002" ) << "hello world!" << '\n';
}

On my machine, this creates files like so:

test.001: hello world!
test.002: 0x8048a01
o.O This is truly unexpected!

I'm guessing this is an instance of calling the member version of
operator<< verses the nonmember version.

In the first line with "test.001", the 1st call to the member version
of operator<<(std::dec) returns a reference to an object, which then
can be used in the nonmember version of operator<<(ostream &, const
char *).

However, in the second line with "test.002", the expression
std::ofstream("test.002") is a temporary object which cannot be bound
to the 1st parameter of the nonmember version operator<<(ostream &,
const char *). Hence, it resorts to some member version of operator<<
which converted const char * to some integer.

Wow. When I thought I've seen the worst, I'm being surprise more and
more to see that C++ truly has some totally-unobvious gotcha's.

I hope the next revision of C++ will address some of these strange codes.

--

-kira

Dec 28 '07 #9
On Dec 27, 3:58 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
If I can bind a reference to a value I can also change that value. But
that is not how a reference works, a reference is a alias for an object
not an object on its own. Therefore a reference can not bind to a rvalue.
Ok, so I suspect it was decided early on that the easiest way to
prevent 'changing' a reference was to disallow setting it to *any* r-
value?

You can never change a reference, only the object it refers to.
I understand. But, the question was:

is the prevention of setting a reference to *any* r-value an easy way
for a compiler to enforce the 'set only once' rule for references, and
if so, was that the rationale for the set-once rule?
And, another question that follows naturally-- 'Why aren't references
allowed to be changed to begin with?' If they were, then the r-value
problem goes away and then the integration of boost's 'shared_ptr'
functionality would be much more seamless at this time.

If you could change a reference then you would have a pointer, and we
already have those. And as we all know pointers are not very safe to
play with. Not sure what you mean with shared_ptr would be more seam-
lessly integrated, though.
But, the point of a reference is to hide that you have a pointer. The
restriction that it be set only once just seems somewhat arbitrary.
After all, in Java and C#, languages where references (and for that
matter, reference-counted smart ptrs) can be set multiple times (and
even to NULL).
I really would have preferred some sort of new syntax to the language
itself instead of tacking on another lib as part of the 'standard'.
For instance, you could use:
int^ x;
to represent a 'smart' ptr in the same way that 'int&' is a reference.

Personally I prefer to keep the stuff in the language to a minimum and
have a library which provides the stuff I need, but that is just me. If
you want a language where everything (well, at least a lot) is hidden
from the programmer with syntactic sugar try C#.
Well, my problem with all the libs for doing this stuff in C++ is the
klunkiness of the syntax. Just take a look inside <functional(STL
header) sometime to see lots of cool features that are added with
klunky syntax.
In a functional language the above would likely mean that g() was a
function taking a function which takes one argument as argument, while
in C++ it means that g() is called with the value returned from f(x).
Not necessarily. In a purely functional language, the x wouldn't be
specified. And, once it is specified, the 'f' that operates on that
specific x comes into existence and the 'g' can subsequently operate
on it. Having a 'g' that can operate on many types of 'f' was not the
point of my example (maybe it was a bad example). But, the point was
that in C++, as well as functional langs, functions transform input
(whether the input is a function or not) and their output can be piped
right into another function, hence resulting, in essence, to a
'transliteration'.

It will certainly be a nice addition to C++ when first-class functions
arrive.
>
1. Are you aware of and understand the difference between a reference
and a const reference?
Yes. With a const reference, you can only call 'const' member
functions (assuming its an object). With a non-const reference, you
can modify at will. Just like anything else const or non-const I
suppose.
2. Can you give an example of when it would be useful to bind a
reference to a r-value?
I can't. But, just scrolling down, the other examples posted are very
nice! In general, every restriction that a lang places is going to
have unintended side effects and there's always a trade-off between
flexibility/power and 'safeness'. In some situations, you just end up
writing code to satisfy a compiler when you know better. ;-)

I don't think that is the case with 'const-correctness' (as another
poster mentioned) of C++, but even that requirement might have corner
cases that I am missing right now. Const-correctness and setting an r-
value into a reference are in two different leagues in my opinion.

--Jonathan
Dec 28 '07 #10
On Dec 27, 3:04 am, Pavel Shved <Pavel.Sh...@gmail.comwrote:
We prefer choosing language after the problem to be solved, not
before. If you `prefer' languages, then go ahead, write all your
programs on perl which surely allows you to return valid reference to
local objects.
I wasn't speaking with any 'problem' in mind except that of specifying
for a computing machine that work which it shall do. I actually
learned to program with C++ and have since moved to Perl and other
'dynamic' languages (Python and Ruby), and others, and am now back
with C++. I've gotta say that moving to those dynamic langs was
definitely a 'freeing' experience, but even better than those, from a
purely theoretical point of view, in my opinion, is my current
interest--Haskell. It has all the benefits of a strongly typed
language and the terseness of functional langs. For me, the closer to
the math a lang is, the more concise and clean it is, the more elegant
and beautiful. After all, programming for the sake of programming
should not be discounted.

The only rationale for using C++ that I've heard lately is for
performance as there are many other modern O-O langs to choose from
(some are even compiled and can perform at least as well such as
Objective-C, but that really only applies if your platform is Apple).
As far as i understand, that's not a `safety' feature, like `const' is
not it as well. It's just a way to imbue pre- and postconditions on
our *source* code. I mean, C++ compiler is so strict because it
encourages programmers to write a program verifiable to some extent.
A program driven by underlying ideas, by underlying concepts and
restrictions (not all! just a couple of, but this little effort makes
its benifit) of their models. But not vice versa which as you seem to
misunderstand is not the right way of writing programs.

That leads to a nice and usefult thing: if your program doesn't fit
your model's requirements it won't compile. Which, in turn, saves
time spent on debugging.
Yea, I definitely agree with this point (especially as it applies to
const-correctness and type-safety). But, even those have unintended
side effects which are a pain to work through at times. Not
everything that is done to satisfy compilers (in fact, a substantial
amount, I think) actually saves time or prevents bugs.

--Jonathan
Dec 28 '07 #11
On 2007-12-28 08:51, johanatan wrote:
On Dec 27, 3:58 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
>If I can bind a reference to a value I can also change that value. But
that is not how a reference works, a reference is a alias for an object
not an object on its own. Therefore a reference can not bind to a rvalue.
Ok, so I suspect it was decided early on that the easiest way to
prevent 'changing' a reference was to disallow setting it to *any* r-
value?

You can never change a reference, only the object it refers to.

I understand. But, the question was:

is the prevention of setting a reference to *any* r-value an easy way
for a compiler to enforce the 'set only once' rule for references, and
if so, was that the rationale for the set-once rule?
No, even if you could bind a reference to a r-value you would not be
able to rebind it later on. That is the way references were designed to
work.
And, another question that follows naturally-- 'Why aren't references
allowed to be changed to begin with?' If they were, then the r-value
problem goes away and then the integration of boost's 'shared_ptr'
functionality would be much more seamless at this time.

If you could change a reference then you would have a pointer, and we
already have those. And as we all know pointers are not very safe to
play with. Not sure what you mean with shared_ptr would be more seam-
lessly integrated, though.

But, the point of a reference is to hide that you have a pointer. The
restriction that it be set only once just seems somewhat arbitrary.
After all, in Java and C#, languages where references (and for that
matter, reference-counted smart ptrs) can be set multiple times (and
even to NULL).
That is because the references of Java and C# are more like pointers
than C++ references, theonly similarity between Java/C# references and
C++ references is the name. The references in C++ are a totally
different concept, in C++ a reference is an alias for an object, if you
think of it that way you can see why they may not be reseated.
>1. Are you aware of and understand the difference between a reference
and a const reference?

Yes. With a const reference, you can only call 'const' member
functions (assuming its an object). With a non-const reference, you
can modify at will. Just like anything else const or non-const I
suppose.
And a const reference can bind to an r-value.
>2. Can you give an example of when it would be useful to bind a
reference to a r-value?

I can't. But, just scrolling down, the other examples posted are very
nice!
Ah, I am starting to see your point (I might be a bit slow, but I
usually get there). You might want to check out the Rvalue references,
which will be part of the next version of C++. I think it could be used
to solve all the problems you, Kai-Uwe Bux, and Pavel Shved mentioned. A
quick overview:
http://www.open-std.org/jtc1/sc22/wg...006/n2027.html

--
Erik Wikström
Dec 28 '07 #12
On Dec 28, 3:37*am, Erik Wikström <Erik-wikst...@telia.comwrote:
But, the point of a reference is to hide that you have a pointer. *The
restriction that it be set only once just seems somewhat arbitrary.
After all, in Java and C#, languages where references (and for that
matter, reference-counted smart ptrs) can be set multiple times (and
even to NULL).

That is because the references of Java and C# are more like pointers
than C++ references, theonly similarity between Java/C# references and
C++ references is the name. The references in C++ are a totally
different concept, in C++ a reference is an alias for an object, if you
think of it that way you can see why they may not be reseated.
That just isn't true (on both technical and conceptual levels).
Technically, a reference in C++ is just a ptr with syntactic sugar to
allow using it just like the object itself instead of dereferencing
the ptr (or using the -operator). Conceptually, they are the same
in the two languages (barring the restrictions already mentioned that C
++ enforces). The only differences I'm aware of between C#/Java and C+
+ with regards to references are:

-. Java references are 'smart' references (i.e., ref counted).
-. Java references can be assigned to NULL.
-. Java references can be set multiple times (and have no restrictions
against setting to r-values).

Under the skin, they are both ptrs (while the Java variant has an
additional ref count and possibly other bookeeping-related (i.e.,
garbage collector) metadata).

I suspect that the reference idea was a step forward for C++ from C
(adding only the syntactic sugar over a regular ptr) and that the
designers of Java took the idea one step further.

--Jonathan
Dec 28 '07 #13
On Dec 27, 1:34*pm, Pavel Shved <Pavel.Sh...@gmail.comwrote:
void retransfer(Object& x)
{
* x.timestamp=now();
* x.transferred=true;
* buf b = allocate_superbuffer(sizeof(x));
* copy_to_superbuffer(b,x);

}

retransfer (a); * *//we want to mark Object a as transferred and pass
it along
retransfer (b+c); *//we want to pass result of b+c along and do not
care much what happens to temporary variable of Object type the result
of operator+ was assigned to.
Well, if C++ will allow binding an r-value to a const reference
(something I haven't verified yet, but makes sense), then you could
factor out the part of retransfer that modifies the object from the
part that simply copies it. Such as:

void copyToSuperBuf(const Object& o)
{
buf b = allocate_superbuffer(sizeof(o));
copy_to_superbuffer(b,o);
}

void retransfer(Object& o)
{
o.timestamp=now();
o.transferred=true;
copyToSuperBuf(o);
}

but that doesn't preclude there being another example that couldn't be
broken up this way I suppose.

--Jonathan
Dec 28 '07 #14
johanatan <jo*******@gmail.comwrites:
On Dec 28, 3:37Â*am, Erik Wikström <Erik-wikst...@telia.comwrote:
But, the point of a reference is to hide that you have a pointer. Â*The
restriction that it be set only once just seems somewhat arbitrary.
After all, in Java and C#, languages where references (and for that
matter, reference-counted smart ptrs) can be set multiple times (and
even to NULL).
That is because the references of Java and C# are more like pointers
than C++ references, theonly similarity between Java/C# references and
C++ references is the name. The references in C++ are a totally
different concept, in C++ a reference is an alias for an object, if you
think of it that way you can see why they may not be reseated.

That just isn't true (on both technical and conceptual levels).
No, *that* just isn't true (on both technical and conceptual
levels). Eric is exactly right: references are aliases for existing
objects. Full stop.
Technically, a reference in C++ is just a ptr with syntactic sugar
to allow using it just like the object itself instead of
dereferencing the ptr (or using the -operator).
No indeed. Pointers can be reseated, can be null, and take a
(platform-specific) number of bytes. References cannot be reseated,
cannot be "null" (although they can be invalid), and don't have a
size.

The compiler may *implement* references internally as pointers, but
that's irrelevent to this discussion.
Conceptually, they are the same in the two languages (barring the
restrictions already mentioned that C ++ enforces).
I think they were *supposed* to be conceptually the same in Java and
in C++, but it didn't really work out that way.
-. Java references are 'smart' references (i.e., ref counted).
-. Java references can be assigned to NULL.
-. Java references can be set multiple times (and have no restrictions
against setting to r-values).
Which are all things you can do with C++ *pointers*, and cannot be
done with C++ *references*. Which is what Eric said, and which I
reiterated.
Under the skin, they are both ptrs (while the Java variant has an
additional ref count and possibly other bookeeping-related (i.e.,
garbage collector) metadata).
Under the skin, C++ references are C++ references, period.
I suspect that the reference idea was a step forward for C++ from C
(adding only the syntactic sugar over a regular ptr) and that the
designers of Java took the idea one step further.
I'd suggest that Java took the idea one step backwards, but that's a
different debate. :-)

--
Dave Steffen - Software Engineer 4

Numerica Corporation (www.numerica.us <http://www.numerica.us/)

Dec 28 '07 #15
On Dec 28, 2:32*pm, Dave Steffen <dgstef...@numerica.uswrote:
johanatan <johana...@gmail.comwrites:
On Dec 28, 3:37*am, Erik Wikström <Erik-wikst...@telia.comwrote:
But, the point of a reference is to hide that you have a pointer. *The
restriction that it be set only once just seems somewhat arbitrary.
After all, in Java and C#, languages where references (and for that
matter, reference-counted smart ptrs) can be set multiple times (and
even to NULL).
That is because the references of Java and C# are more like pointers
than C++ references, theonly similarity between Java/C# references and
C++ references is the name. The references in C++ are a totally
different concept, in C++ a reference is an alias for an object, if you
think of it that way you can see why they may not be reseated.
That just isn't true (on both technical and conceptual levels).

*No, *that* just isn't true (on both technical and conceptual
*levels). *Eric is exactly right: references are aliases for existing
*objects. *Full stop.
If that's true, why is it recommended to pass large objects by
reference? It is to save memory, no? The shortest amount of memory
that you could use to 'alias' an object is a ptr. If you choose
instead to use some kind of opaque reference under the skin (the only
other option), it would still in essence be a 'ptr'. Conceptually, it
certainly 'points' to the object and in practice in every compiler
I've ever seen, this translates to an actual pointer. It would be
quite unorthodox to do something different, though it certainly is
possible.
Technically, a reference in C++ is just a ptr with syntactic sugar
to allow using it just like the object itself instead of
dereferencing the ptr (or using the -operator).

*No indeed. *Pointers can be reseated, can be null, and take a
*(platform-specific) number of bytes. *References cannot be reseated,
*cannot be "null" (although they can be invalid), and don't have a
*size.
My point was the references are wrappers around pointers
(conceptually) that hide some of the features and add others
(specifically the syntactic sugar). I was in no way suggesting that
you can do everything with a reference that you can do with a pointer
(a fact evidenced by this very discussion about the differences).
*The compiler may *implement* references internally as pointers, but
*that's irrelevent to this discussion.
Actually, I think it's quite relevant. Take a look at some
disassembly sometime if you're not convinced. As I mentioned
previously, a compiler could choose some other form of opaque
reference under the skin, but that would be quite a stretch for it do
so (and it would have to have some very strong rationale for doing so
which at this point is completely theoretical).
*Conceptually, they are the same in the two languages (barring the
restrictions already mentioned that C ++ enforces).

*I think they were *supposed* to be conceptually the same in Java and
*in C++, but it didn't really work out that way.
-. Java references are 'smart' references (i.e., ref counted).
-. Java references can be assigned to NULL.
-. Java references can be set multiple times (and have no restrictions
against setting to r-values).

*Which are all things you can do with C++ *pointers*, and cannot be
*done with C++ *references*. *Which is what Eric said, and which I
*reiterated.
Well, the obvious difference between references and pointers is that
the references 'look' like the objects themselves (which is exactly
the way they work in Java), something I have referred to previously as
'syntactic sugar'.
Under the skin, they are both ptrs (while the Java variant has an
additional ref count and possibly other bookeeping-related (i.e.,
garbage collector) metadata).

* Under the skin, C++ references are C++ references, period.
I suspect that the reference idea was a step forward for C++ from C
(adding only the syntactic sugar over a regular ptr) and that the
designers of Java took the idea one step further.

* I'd suggest that Java took the idea one step backwards, but that's a
* different debate. :-)
Depends on whether you value human time or computer time more I
suppose. As computer time becomes dirt cheap, I think you'll start
valuing human time more.

--Jonathan
Dec 28 '07 #16
Dave Steffen wrote:
johanatan <jo*******@gmail.comwrites:
>On Dec 28, 3:37*am, Erik Wikström <Erik-wikst...@telia.comwrote:
But, the point of a reference is to hide that you have a pointer.
The restriction that it be set only once just seems somewhat
arbitrary. After all, in Java and C#, languages where references (and
for that matter, reference-counted smart ptrs) can be set multiple
times (and even to NULL).

That is because the references of Java and C# are more like pointers
than C++ references, theonly similarity between Java/C# references and
C++ references is the name. The references in C++ are a totally
different concept, in C++ a reference is an alias for an object, if you
think of it that way you can see why they may not be reseated.

That just isn't true (on both technical and conceptual levels).

No, *that* just isn't true (on both technical and conceptual
levels). Eric is exactly right: references are aliases for existing
objects. Full stop.
That is misleading in that it could create the misconception that references
only bind to pre-existing objects (objects that exist independently of the
attempt of binding a reference to them).

When an rvalue of class type is used to initialize a const reference, the
implementation is allowed to make a copy of that object first and then bind
the reference to an object that would not even exist if you had not tried
to bind it to a reference. In that case, the reference is not an alias for
the object used to initialize the reference but for a different object that
even can have different cv-qualifications. This is the reason that, sadly,
the following method to obtain a reference to a non-const temporary is
flawed:

/*
| lvalue_cast( non-const expression ) creates an lvalue out
| of anything, including a temporary. Just make sure, the
| expression is not constant.
*/

template < typename T >
T & lvalue_cast ( const T & ref ) {
return( const_cast< T & >( ref ) );
}
The C++ standard does not say what references are. In particular, it does
not claim references to be aliases. It only defines how they contribute to
the observable behavior of a program. The precise rules are complicated and
cannot be deduced or guessed from the slogan that references are aliases
for objects.
Best

Kai-Uwe Bux
Dec 29 '07 #17
On 2007-12-29 00:14, johanatan wrote:
On Dec 28, 2:32 pm, Dave Steffen <dgstef...@numerica.uswrote:
>johanatan <johana...@gmail.comwrites:
On Dec 28, 3:37 am, Erik Wikström <Erik-wikst...@telia.comwrote:
But, the point of a reference is to hide that you have a pointer. The
restriction that it be set only once just seems somewhat arbitrary.
After all, in Java and C#, languages where references (and for that
matter, reference-counted smart ptrs) can be set multiple times (and
even to NULL).
That is because the references of Java and C# are more like pointers
than C++ references, theonly similarity between Java/C# references and
C++ references is the name. The references in C++ are a totally
different concept, in C++ a reference is an alias for an object, if you
think of it that way you can see why they may not be reseated.
That just isn't true (on both technical and conceptual levels).

No, *that* just isn't true (on both technical and conceptual
levels). Eric is exactly right: references are aliases for existing
objects. Full stop.

If that's true, why is it recommended to pass large objects by
reference? It is to save memory, no? The shortest amount of memory
that you could use to 'alias' an object is a ptr.
Actually not quite true, since a pointer, as opposed to a reference, is
an object in its own right it must also have an address (take up some
amount of memory). This means that a compiler can in some situation more
easily optimise away references, especially to objects at a know offset
on the stack, where the pointer have to be included.
If you choose
instead to use some kind of opaque reference under the skin (the only
other option), it would still in essence be a 'ptr'. Conceptually, it
certainly 'points' to the object and in practice in every compiler
I've ever seen, this translates to an actual pointer. It would be
quite unorthodox to do something different, though it certainly is
possible.
Quite true that in most cases they are implemented as pointers, but
conceptually (from the way they behave) they are very different from
pointers. And using the same conceptual view a Java reference have more
in common with a C++ pointer than with a reference.
Technically, a reference in C++ is just a ptr with syntactic sugar
to allow using it just like the object itself instead of
dereferencing the ptr (or using the -operator).

No indeed. Pointers can be reseated, can be null, and take a
(platform-specific) number of bytes. References cannot be reseated,
cannot be "null" (although they can be invalid), and don't have a
size.

My point was the references are wrappers around pointers
(conceptually) that hide some of the features and add others
(specifically the syntactic sugar). I was in no way suggesting that
you can do everything with a reference that you can do with a pointer
(a fact evidenced by this very discussion about the differences).
That is not conceptually, that is implementation details.
> The compiler may *implement* references internally as pointers, but
that's irrelevent to this discussion.

Actually, I think it's quite relevant. Take a look at some
disassembly sometime if you're not convinced. As I mentioned
previously, a compiler could choose some other form of opaque
reference under the skin, but that would be quite a stretch for it do
so (and it would have to have some very strong rationale for doing so
which at this point is completely theoretical).
Actually it is very relevant, the C++ standard only defines how the
different concepts work, not how they are implemented. When comparing
pointers and references it is their behaviour that counts, not how it is
achieved.
Conceptually, they are the same in the two languages (barring the
restrictions already mentioned that C ++ enforces).

I think they were *supposed* to be conceptually the same in Java and
in C++, but it didn't really work out that way.
Hardly, C++ concepts had been around for some years before Java came to
the scene, the Java references were inspired from some other language.
While I do not remember the genealogy I would suspect Smalltalk or one
of those early OO languages.
-. Java references are 'smart' references (i.e., ref counted).
-. Java references can be assigned to NULL.
-. Java references can be set multiple times (and have no restrictions
against setting to r-values).

Which are all things you can do with C++ *pointers*, and cannot be
done with C++ *references*. Which is what Eric said, and which I
reiterated.

Well, the obvious difference between references and pointers is that
the references 'look' like the objects themselves (which is exactly
the way they work in Java), something I have referred to previously as
'syntactic sugar'.
Personally I would call that a superficial difference, sure it is the
most obvious difference for one new to pointers and references but if
that was all it was to it I doubt that someone would have felt the need
to add references in the first place.

--
Erik Wikström
Dec 29 '07 #18
On Dec 28, 5:40*pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-12-29 00:14, johanatan wrote:
*No, *that* just isn't true (on both technical and conceptual
*levels). *Eric is exactly right: references are aliases for existing
*objects. *Full stop.
If that's true, why is it recommended to pass large objects by
reference? *It is to save memory, no? *The shortest amount of memory
that you could use to 'alias' an object is a ptr.

Actually not quite true, since a pointer, as opposed to a reference, is
an object in its own right it must also have an address (take up some
amount of memory). This means that a compiler can in some situation more
easily optimise away references, especially to objects at a know offset
on the stack, where the pointer have to be included.
You are talking about compiler optimizations which can be applied
whether a ptr or ref is used. The same optimizations can be applied
equally well to either (similar to inlining it sounds like) and if you
would accept what I'm telling you, a reference is compiled to exactly
the same thing as a ptr.

Suppose you have a ref like this:

int****&

We would agree on the first 4 asterisks, no? Those are definitely
ptrs, right? It's only that last level of indirection that is in
dispute, right? What construct do we have at our disposal (in
assembly, C, C++) to bridge that last level of indirection? I would
highly recommend that if you decide to write a compiler, that you
consider our old friend-- the ptr!
If you choose
instead to use some kind of opaque reference under the skin (the only
other option), it would still in essence be a 'ptr'. *Conceptually, it
certainly 'points' to the object and in practice in every compiler
I've ever seen, this translates to an actual pointer. *It would be
quite unorthodox to do something different, though it certainly is
possible.

Quite true that in most cases they are implemented as pointers, but
conceptually (from the way they behave) they are very different from
pointers. And using the same conceptual view a Java reference have more
in common with a C++ pointer than with a reference.
Imaging that you knew C (or possibly even assembly) before you learned
C++. How did you pass things by reference? I'll leave the code
example for you to write if you don't see this point.
Technically, a reference in C++ is just a ptr with syntactic sugar
to allow using it just like the object itself instead of
dereferencing the ptr (or using the -operator).
*No indeed. *Pointers can be reseated, can be null, and take a
*(platform-specific) number of bytes. *References cannot be reseated,
*cannot be "null" (although they can be invalid), and don't have a
*size.
My point was the references are wrappers around pointers
(conceptually) that hide some of the features and add others
(specifically the syntactic sugar). *I was in no way suggesting that
you can do everything with a reference that you can do with a pointer
(a fact evidenced by this very discussion about the differences).

That is not conceptually, that is implementation details.
When I say conceptual, I mean literally that--a concept in the brain.
Are you telling me that you can't *think* of references as ptrs under
the skin?
*The compiler may *implement* references internally as pointers, but
*that's irrelevent to this discussion.
Actually, I think it's quite relevant. *Take a look at some
disassembly sometime if you're not convinced. *As I mentioned
previously, a compiler could choose some other form of opaque
reference under the skin, but that would be quite a stretch for it do
so (and it would have to have some very strong rationale for doing so
which at this point is completely theoretical).

Actually it is very relevant, the C++ standard only defines how the
different concepts work, not how they are implemented. When comparing
pointers and references it is their behaviour that counts, not how it is
achieved.
Have you ever programmed in Java or C#? The reference certainly feels
the same whether you are in C++ or Java or C#. The only difference
are the little gotchas that are more plentiful in C++ (i.e., special
cases) due to what is really a handicapped reference (when compared
objectively to the theoretical concept) that in C++ was no more than a
piece of syntactic sugar for hiding a level of indirection (one level,
presumably the last).
*Conceptually, they are the same in the two languages (barring the
restrictions already mentioned that C ++ enforces).
*I think they were *supposed* to be conceptually the same in Java and
*in C++, but it didn't really work out that way.

Hardly, C++ concepts had been around for some years before Java came to
the scene, the Java references were inspired from some other language.
While I do not remember the genealogy I would suspect Smalltalk or one
of those early OO languages.
Yes, surely. Most CS concepts are not new but were invented in the
60's and 70's and have been repackaged or renamed over time.
Designers of languages are just like the general population in some
senses--susceptible to what is fashionable or 'in style'. I was
theorizing that C++ was merely one implementation of the reference
which was the inspiration for Java purely because of its popularity.
After all, many other langs have had such a concept, but very few
provided so much of the structure of the language of Java as C++.
Surely you see the similarity in syntax between Java and C++?
-. Java references are 'smart' references (i.e., ref counted).
-. Java references can be assigned to NULL.
-. Java references can be set multiple times (and have no restrictions
against setting to r-values).
*Which are all things you can do with C++ *pointers*, and cannot be
*done with C++ *references*. *Which is what Eric said, and which I
*reiterated.
Well, the obvious difference between references and pointers is that
the references 'look' like the objects themselves (which is exactly
the way they work in Java), something I have referred to previously as
'syntactic sugar'.

Personally I would call that a superficial difference, sure it is the
most obvious difference for one new to pointers and references but if
that was all it was to it I doubt that someone would have felt the need
to add references in the first place.
For you, the superficial difference is for me the main feature. I see
all the other gotchas regarding refs in C++ as merely superficial side
effects of various constraints operating in conjunction with one
another (i.e., emergence, in this case-- not very pretty emergence).

I guess we'll just have to agree to disagree on the 'superficiality'
of the various aspects of refs.

--Jonathan
Dec 29 '07 #19
johanatan wrote:
: On Dec 28, 5:40 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
:: On 2007-12-29 00:14, johanatan wrote:
:
: You are talking about compiler optimizations which can be applied
: whether a ptr or ref is used. The same optimizations can be applied
: equally well to either (similar to inlining it sounds like) and if
: you would accept what I'm telling you, a reference is compiled to
: exactly the same thing as a ptr.

That's an implementation detail.

You wouldn't say that an int and and unsigned int is the same, just
beacuse the bit patterns look the same for the value 42.

:
: Suppose you have a ref like this:
:
: int****&
:
: We would agree on the first 4 asterisks, no? Those are definitely
: ptrs, right? It's only that last level of indirection that is in
: dispute, right? What construct do we have at our disposal (in
: assembly, C, C++) to bridge that last level of indirection? I would
: highly recommend that if you decide to write a compiler, that you
: consider our old friend-- the ptr!

That's an implementation detail. :-)

:
: Imaging that you knew C (or possibly even assembly) before you
: learned C++. How did you pass things by reference? I'll leave the
: code example for you to write if you don't see this point.

In C you only have pass by value, so you have to simulate anything
else by taking the address of an object, and passing the resulting
pointer by value.

A reference doesn't point to anything, it refers to an object.

:
::::: Technically, a reference in C++ is just a ptr with syntactic
::::: sugar
::::: to allow using it just like the object itself instead of
::::: dereferencing the ptr (or using the -operator).
::
:::: No indeed. Pointers can be reseated, can be null, and take a
:::: (platform-specific) number of bytes. References cannot be
:::: reseated, cannot be "null" (although they can be invalid), and
:::: don't have a size.
::
::: My point was the references are wrappers around pointers
::: (conceptually) that hide some of the features and add others
::: (specifically the syntactic sugar). I was in no way suggesting
::: that you can do everything with a reference that you can do with
::: a pointer (a fact evidenced by this very discussion about the
::: differences).
::
:: That is not conceptually, that is implementation details.
::
:
: When I say conceptual, I mean literally that--a concept in the
: brain.

It's also a concept of the language. A programming language is all
about abstractions.

A reference is a totally different abstraction than a pointer. That's
why we have both, and that's why they behave differently.

: Are you telling me that you can't *think* of references as
: ptrs under the skin?

I think he is saying that you shouldn't think of a reference as a
pointer, just because they are implemented similary on some hardware.
Just like you shouldn't think that an int is a long, just becase they
are on some compilers (but not on others).

:
: Yes, surely. Most CS concepts are not new but were invented in the
: 60's and 70's and have been repackaged or renamed over time.
: Designers of languages are just like the general population in some
: senses--susceptible to what is fashionable or 'in style'. I was
: theorizing that C++ was merely one implementation of the reference
: which was the inspiration for Java purely because of its popularity.
: After all, many other langs have had such a concept, but very few
: provided so much of the structure of the language of Java as C++.
: Surely you see the similarity in syntax between Java and C++?

No, Java and C++ just looks similar, because they have borrowed syntax
elements from C. The ideas behind the languages are different. That
makes things that looks similar actually behave differently.

:
::::: -. Java references are 'smart' references (i.e., ref counted).
::::: -. Java references can be assigned to NULL.
::::: -. Java references can be set multiple times (and have no
::::: restrictions against setting to r-values).
::

Java references are smart pointers. We have got those in C++ as well.

Bo Persson
Dec 29 '07 #20
On 2007-12-29 03:31, johanatan wrote:
On Dec 28, 5:40 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
>On 2007-12-29 00:14, johanatan wrote:
> No, *that* just isn't true (on both technical and conceptual
levels). Eric is exactly right: references are aliases for existing
objects. Full stop.
If that's true, why is it recommended to pass large objects by
reference? It is to save memory, no? The shortest amount of memory
that you could use to 'alias' an object is a ptr.

Actually not quite true, since a pointer, as opposed to a reference, is
an object in its own right it must also have an address (take up some
amount of memory). This means that a compiler can in some situation more
easily optimise away references, especially to objects at a know offset
on the stack, where the pointer have to be included.

You are talking about compiler optimizations which can be applied
whether a ptr or ref is used. The same optimizations can be applied
equally well to either (similar to inlining it sounds like) and if you
would accept what I'm telling you, a reference is compiled to exactly
the same thing as a ptr.

Suppose you have a ref like this:

int****&

We would agree on the first 4 asterisks, no? Those are definitely
ptrs, right? It's only that last level of indirection that is in
dispute, right? What construct do we have at our disposal (in
assembly, C, C++) to bridge that last level of indirection? I would
highly recommend that if you decide to write a compiler, that you
consider our old friend-- the ptr!
Of course, but I am not talking about how to implement them. How the
compiler makes a reference do what it does is unimportant, there are
hundreds of ways to implement references (though few effective). What is
important is the fact that pointers and references have very different
semantics.
If you choose
instead to use some kind of opaque reference under the skin (the only
other option), it would still in essence be a 'ptr'. Conceptually, it
certainly 'points' to the object and in practice in every compiler
I've ever seen, this translates to an actual pointer. It would be
quite unorthodox to do something different, though it certainly is
possible.

Quite true that in most cases they are implemented as pointers, but
conceptually (from the way they behave) they are very different from
pointers. And using the same conceptual view a Java reference have more
in common with a C++ pointer than with a reference.

Imaging that you knew C (or possibly even assembly) before you learned
C++. How did you pass things by reference? I'll leave the code
example for you to write if you don't see this point.
Again, that is an implementation detail and does not have any bearing on
whether references and pointers are similar or not. Would you consider
the following two "concepts" identical just because they have the same
implementation too?

// A point in space
struct Point
{
double x, y, z;
};

// A Point on a curve
struct FuncVal
{
double x; // The x value
double fx; // f(x)
double d; // f'(x)
};
Technically, a reference in C++ is just a ptr with syntactic sugar
to allow using it just like the object itself instead of
dereferencing the ptr (or using the -operator).
> No indeed. Pointers can be reseated, can be null, and take a
(platform-specific) number of bytes. References cannot be reseated,
cannot be "null" (although they can be invalid), and don't have a
size.
My point was the references are wrappers around pointers
(conceptually) that hide some of the features and add others
(specifically the syntactic sugar). I was in no way suggesting that
you can do everything with a reference that you can do with a pointer
(a fact evidenced by this very discussion about the differences).

That is not conceptually, that is implementation details.

When I say conceptual, I mean literally that--a concept in the brain.
Are you telling me that you can't *think* of references as ptrs under
the skin?
I can think of them that way, but that is not how I think of references,
because that is an implementation detail. When I think of a C++
reference it is in the terms of its semantics.
> The compiler may *implement* references internally as pointers, but
that's irrelevent to this discussion.
Actually, I think it's quite relevant. Take a look at some
disassembly sometime if you're not convinced. As I mentioned
previously, a compiler could choose some other form of opaque
reference under the skin, but that would be quite a stretch for it do
so (and it would have to have some very strong rationale for doing so
which at this point is completely theoretical).

Actually it is very relevant, the C++ standard only defines how the
different concepts work, not how they are implemented. When comparing
pointers and references it is their behaviour that counts, not how it is
achieved.

Have you ever programmed in Java or C#? The reference certainly feels
the same whether you are in C++ or Java or C#. The only difference
are the little gotchas that are more plentiful in C++ (i.e., special
cases) due to what is really a handicapped reference (when compared
objectively to the theoretical concept) that in C++ was no more than a
piece of syntactic sugar for hiding a level of indirection (one level,
presumably the last).
I have programmed in both Java and C# and a few others, but I do not
agree about references feeling the same. For one thing reseating a
reference in both Java and # is natural, in C++ I would have to use a
(smart-)pointer to do that. Nor do I feel that the C++ references are
handicapped versions of the Java and C# references, since they do not
sever the same purpose. Its like saying a drill is a handicapped saw,
sure both make holes, but not the same kinds of holes and you do not use
them for the same tasks.

The Java and C# references are what the C++ pointers would have looked
like if there had been no need for backwards compatibility with C
(pointer arithmetics) and no manual memory management.
-. Java references are 'smart' references (i.e., ref counted).
-. Java references can be assigned to NULL.
-. Java references can be set multiple times (and have no restrictions
against setting to r-values).
> Which are all things you can do with C++ *pointers*, and cannot be
done with C++ *references*. Which is what Eric said, and which I
reiterated.
Well, the obvious difference between references and pointers is that
the references 'look' like the objects themselves (which is exactly
the way they work in Java), something I have referred to previously as
'syntactic sugar'.

Personally I would call that a superficial difference, sure it is the
most obvious difference for one new to pointers and references but if
that was all it was to it I doubt that someone would have felt the need
to add references in the first place.

For you, the superficial difference is for me the main feature. I see
all the other gotchas regarding refs in C++ as merely superficial side
effects of various constraints operating in conjunction with one
another (i.e., emergence, in this case-- not very pretty emergence).
Not sure what you mean by emergence.

--
Erik Wikström
Dec 29 '07 #21
On 2007-12-29 03:56, johanatan wrote:
On Dec 28, 4:24 pm, jkherci...@gmx.net wrote:
The C++ standard does not say what references are. In particular,
it does
>not claim references to be aliases. It only defines how they contribute to
the observable behavior of a program. The precise rules are complicated and
cannot be deduced or guessed from the slogan that references are aliases
for objects.

Yes. Exactly. A little digging around the net turned up this page
(which provides a little bkg info on how the 'alias' notion is being
promoted):

http://www-cs-students.stanford.edu/...nfo/references

It seems that the idea of an alias is some academic's way of coming up
with a concept that is easier to understand than 'ptr'.
Actually I would think, but I could be wrong, that the idea comes from
TC++PL where it says in §5.5 (freely translated from Swedish) "A
reference is an alternative name for an object." But then again, BS is
an academic.

--
Erik Wikström
Dec 29 '07 #22
On Dec 29, 3:57*am, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-12-29 03:56, johanatan wrote:
On Dec 28, 4:24 pm, jkherci...@gmx.net wrote:
*The C++ standard does not say what references are. In particular,
it does
not claim references to be aliases. It only defines how they contributeto
the observable behavior of a program. The precise rules are complicatedand
cannot be deduced or guessed from the slogan that references are aliases
for objects.
Yes. *Exactly. *A little digging around the net turned up this page
(which provides a little bkg info on how the 'alias' notion is being
promoted):
http://www-cs-students.stanford.edu/...nfo/references
It seems that the idea of an alias is some academic's way of coming up
with a concept that is easier to understand than 'ptr'.

Actually I would think, but I could be wrong, that the idea comes from
TC++PL where it says in §5.5 (freely translated from Swedish) "A
reference is an alternative name for an object." But then again, BS is
an academic.
Well, for a C programmer, it's going to be very tempting to think of a
reference in the context of 'pass-by-reference' which in C is
accomplished by a ptr. And, that's the main use for references in C++
too, right? To pass something by reference to avoid a potentially
large copy (and to have any changes inside the inner scope propagated
back out to the caller). As I said previously, Bjarne could have
chosen something other than 'reference' and that would have avoided
the almost automatic mental connection to passing by reference in C.

I think if you interviewed some C programmers that made the transition
to C++ in the early days, that you'd find they most likely thought of
them in that way (though I wasn't there and can't say for sure--just
the impression I've gotten from professors and colleagues).

I'm the type of person that is content with abstractions, but after
you know what is *really* going on, why forget it? I can tell you
from experience that none of my programs have ever been adversely
affected by my 'concept' of what a reference is.

--Jonathan
Dec 30 '07 #23
On Dec 29, 12:23*am, "Bo Persson" <b...@gmb.dkwrote:
I think he is saying that you shouldn't think of a reference as a
pointer, just because they are implemented similary on some hardware.
Just like you shouldn't think that an int is a long, just becase they
are on some compilers (but not on others).
Point taken. But, if an alternate implementation of references ever
comes out, I'd like to know how it works too, because that's just the
curious person I am. In the grand scheme of things, I think this is
probably something that isn't as likely to change from compiler to
compiler (or in future), but if it ever does, and I need to do some
optimization, then at that time, I will learn the alternate impl.

Can anyone seriously think of an alternate implementation of reference
that didn't include at least a ptr to the original object?

For me, everything that I do in C++ ultimately involves some thought
process about what it must be being compiled to (and in cases where
optimization is called for, an actual reading of the disassembly).
Now, with Haskell, this really is a black-box language. It is not
clear how lazy evaluation and infinite lists and so on translate to
assembly (but in C and C++, it's much easier) so I'm stuck just
working with the abstract concepts in it (at least at this point).

--Jonathan
Dec 30 '07 #24
On Dec 28, 8:04*pm, jkherci...@gmx.net wrote:
All other programmers should be busy enough worrying about the life-time of
objects bound to references and the provisions for initializing references..
None of those are intuitive and none of those are successfully captured in
any of the nutshell-explanations for references. I find that neither the
talk about aliases nor the comparison with pointers is helpful in dealing
with references. There is nothing more (but also nothing less!) to
references than the specs from the standard; and those rules are
complicated and cannot be captured by a simple slogan or comparison.
That might be true for you and I do agree that lifetimes and such are
far more important things to worry about. But, I don't see the harm
in thinking of them as ptrs. To each his own I suppose. There seems
to be 3 types of ppl here, those who prefer to think of them as
aliases and those who think of them as wrapped and enhanced (though
limited in other ways) ptrs. And, then you, who sticks directly to
the standard (which I must say I've never read or needed to). I
always let the compiler tell me when I'm trying to do something non-
standard (as it is concerned). And, I've never had to write platform
independent code, so the compiler is usually the last word for me
about standards (and most compilers are non-standard to begin with).

I'm sure everyone involved in this discussion are very competent
programmers and so what works for them, works for them. :-)

--Jonathan
Dec 30 '07 #25
On Dec 29, 11:51*pm, jkherci...@gmx.net wrote:
If you insist on adding pictures like that to your mental environment, I
won't try to stop you. I just don't feel the need, and I think that when
push comes to shove those pictures are misleading and harmful.
I think we both agree on this point (and most others too actually).
It's just that I think 'alias' is the more offensive mental model than
'pointer' (though surely neither are needed).

Also, please realize that the end of my last msg was in response to
your msg, but was not directed to you (it was to the 'alias'-
supporters).

--Jonathan
Dec 30 '07 #26
On Dec 29, 11:51*pm, jkherci...@gmx.net wrote:
My point
was that someone who knows how the inner parts work in practice will
be better able to make decisions than those who don't.

Anyone who thinks about references in terms of broken metaphors will make
worse decisions than someone who knows the precise rules.
It would be really nice if people would take my words for what they
say instead of what they want them to say or what they think they
say. The point was that someone who knows the inner workings (as well
as the precise rules) is better able to make decisions than someone
who knows only the precise rules.

This isn't the first time a straw man has been setup and argued
against, but it is a very clear one that I thought I should point out.

--Jonathan
Dec 30 '07 #27
On Dec 27, 12:49 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-12-27 02:19, johanatan wrote:
On Dec 26, 6:33 am, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-12-26 06:01, johanatan wrote:
On Dec 25, 3:00 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
Foo& Bar( int Val )
{
return Foo( Val );
}
Will not work, can not convert Foo to Foo&
Should work, but not a very useful thing to do as local
copy dies immediately.
Should not work, a reference can not bind to a rvalue.
Ok, you're right. I just tried this again in Ch (a C++
interpreter) -- apparently the method wasn't being called
before and so wasn't compiled.
Does not work, same thing, can not convert Foo to Foo&.
Should also work. Something else is going on as that
syntax is compiling fine in my compiler.
Get a new compiler. Once again, you can not bind a
reference to a rvalue.
This is certainly an interesting design decision of C++. I
suspect it was a 'safety' feature built in, but I prefer
languages to be more flexible by inferring as much as
possible from context. What is the danger of binding to an
r-value?
Consider the following code:
int& r = 5;
r = 6;
If I can bind a reference to a value I can also change that
value. But that is not how a reference works, a reference is a
alias for an object not an object on its own. Therefore a
reference can not bind to a rvalue.
That's an interesting example, and a very good reason for not
allowing using an rvalue to initialize a reference. Still, the
original language (pre-1988, roughly, so we're talking about a
very long time ago) did allow using an rvalue to initialize any
reference, with more or less the same semantics which currently
apply when an rvalue is used to initialize a reference to const.
The rule was changed because it was found, in practice, to be
too great a source of errors. IMHO, the real problem is that
there are too many implicit conversions, and that the result of
an implicit conversion is an rvalue; the errors are typically
cases where an implicit conversion resulted in an rvalue when
the programmer expected an lvalue. Things like:

void
increment( int& i )
{
++ i ;
}

int
main()
{
unsigned x = 0 ;
increment( x ) ;
std::cout << x << std::endl ;
return 0 ;
}

which, of course, results in 0.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Dec 30 '07 #28
On Dec 28, 11:15 pm, johanatan <johana...@gmail.comwrote:
On Dec 28, 3:37 am, Erik Wikström <Erik-wikst...@telia.comwrote:
But, the point of a reference is to hide that you have a pointer. The
restriction that it be set only once just seems somewhat arbitrary.
After all, in Java and C#, languages where references (and for that
matter, reference-counted smart ptrs) can be set multiple times (and
even to NULL).
That is because the references of Java and C# are more like pointers
than C++ references, theonly similarity between Java/C# references and
C++ references is the name. The references in C++ are a totally
different concept, in C++ a reference is an alias for an object, if you
think of it that way you can see why they may not be reseated.
That just isn't true (on both technical and conceptual levels).
Technically, a reference in C++ is just a ptr with syntactic sugar to
allow using it just like the object itself instead of dereferencing
the ptr (or using the -operator).
Not really. A C++ reference is a more or less an alias for an
object. It can't be null, and it can't be reseated.
Comparisons with Java and C# don't make much sense, either,
because the object model is different: in C++, a pointer is an
object, just like an int or anything else, and you can take the
actual address of anything---in Java (and C#?), only class types
can be objects, you can only have a reference (or pointer) to a
class type, and all objects of class types must be dynamically
allocated. Globally considered, references in Java are as exact
an equivalent to C++ pointers as you can have, given the object
model of Java.
Conceptually, they are the same in the two languages (barring
the restrictions already mentioned that C ++ enforces). The
only differences I'm aware of between C#/Java and C+ + with
regards to references are:
-. Java references are 'smart' references (i.e., ref counted).
Not in any Java implementation I've seen or heard of.
-. Java references can be assigned to NULL.
Like C++ pointers.
-. Java references can be set multiple times (and have no
restrictions against setting to r-values).
Java doesn't have rvalues, at least, not in the sense C++ does.
In C++, a pointer can be set multiple times, as in Java. And
you need to jump through hoops to get it to point to an rvalue,
since you cannot directly take the address of an rvalue (and of
course, an object allocated by new is not an rvalue).

So far, you've shown that references in Java are the equivalent
of pointers in C++, not the equivalent of references.
Under the skin, they are both ptrs
That's one possible implementation of references in C++, but the
language has been carefully designed so that a conforming
program cannot tell.
(while the Java variant has an additional ref count and
possibly other bookeeping-related (i.e., garbage collector)
metadata).
I suspect that the reference idea was a step forward for C++
from C (adding only the syntactic sugar over a regular ptr)
and that the designers of Java took the idea one step further.
No. I think that the original motivation for references in C++
is linked with operator overloading; they allow writing an
operator+ which doesn't require a deep copy of both of its
arguments, but can still be called with the usual syntax. The
designers of Java based there references on C++ (and C)
pointers, simply eliminating features which they felt were too
dangerous (like pointer arithmetic) or which didn't fit into the
object model. (For that matter, pointer arithmetic really
wouldn't fit into the Java object model either.) The choice of
the name was purely based on the supposed reputation that
pointers were dangerous, and that in a "safe" language, you
can't have pointers. (Marketing, in sum.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Dec 30 '07 #29
johanatan wrote:
On Dec 29, 11:51*pm, jkherci...@gmx.net wrote:
My point
was that someone who knows how the inner parts work in practice will
be better able to make decisions than those who don't.

Anyone who thinks about references in terms of broken metaphors will make
worse decisions than someone who knows the precise rules.

It would be really nice if people would take my words for what they
say instead of what they want them to say or what they think they
say. The point was that someone who knows the inner workings (as well
as the precise rules) is better able to make decisions than someone
who knows only the precise rules.
I do not engage in reading minds but only in reading what people write. Your
claim did read like so:

someone who knows how the inner parts work in practice will
be better able to make decisions than those who don't

and neither like this:

someone who knows how the inner parts work and knows the precise rules
will be better able to make decisions than those who don't.
nor like this:

someone who knows how the inner parts work and knows the precise rules
will be better able to make decisions than those who only know the rules.

Besides, if you read what you quote carefully, you will find that I did not
contradict you anyway. I just provided an additional point of view.
With regard to your clarified position, I find that the situations where
knowledge of the inner workings of references (given a particular compiler
and in addition to knowledge of the rules from the standard) is useful in
decision making are rather limited (in fact, just about nothing comes to
mind). However, that might just be a lack of imagination and experience on
my part. Could you provide some examples for the kind of decision making
you are thinking of?
Best

Kai-Uwe Bux
Dec 30 '07 #30
On Dec 30, 8:21 am, johanatan <johana...@gmail.comwrote:
On Dec 29, 12:23 am, "Bo Persson" <b...@gmb.dkwrote:
I think he is saying that you shouldn't think of a reference as a
pointer, just because they are implemented similary on some hardware.
Just like you shouldn't think that an int is a long, just becase they
are on some compilers (but not on others).
Point taken. But, if an alternate implementation of references ever
comes out, I'd like to know how it works too, because that's just the
curious person I am.
The C++ standard says explicitly that it is unspecified whether
a reference occupies memory or not. All compilers I know do
implement it as a pointer in some cases, and all implement it
without using any memory what so ever in others, by simply
tracking at compile time what is refered to.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Dec 30 '07 #31
On Dec 30, 8:50 am, johanatan <johana...@gmail.comwrote:
On Dec 28, 8:04 pm, jkherci...@gmx.net wrote:
All other programmers should be busy enough worrying about
the life-time of objects bound to references and the
provisions for initializing references. None of those are
intuitive and none of those are successfully captured in any
of the nutshell-explanations for references. I find that
neither the talk about aliases nor the comparison with
pointers is helpful in dealing with references. There is
nothing more (but also nothing less!) to references than the
specs from the standard; and those rules are complicated and
cannot be captured by a simple slogan or comparison.
That might be true for you and I do agree that lifetimes and
such are far more important things to worry about. But, I
don't see the harm in thinking of them as ptrs.
To a point, I agree. One can say that C++ has two types of
pointers, one of which is called a reference. The problem is
that the second one is called a pointer in all of the existing
literature, so using the term pointer for both would be a major
source of confusion.

The important point is that in C++, pointers and references do
have significant and important differences. More so, almost,
than pointers and ints. (Both ints and pointers are objects,
with an address. For that matter, you can do arithmetic on
pointers as well.) And that the two types of "pointers" that
C++ has, are far from the only two types one can imagine.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Dec 30 '07 #32
On Dec 29, 12:57 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-12-29 03:56, johanatan wrote:
On Dec 28, 4:24 pm, jkherci...@gmx.net wrote:
The C++ standard does not say what references are. In
particular, it does not claim references to be aliases. It
only defines how they contribute to the observable behavior
of a program. The precise rules are complicated and cannot
be deduced or guessed from the slogan that references are
aliases for objects.
Yes. Exactly. A little digging around the net turned up
this page (which provides a little bkg info on how the
'alias' notion is being promoted):
http://www-cs-students.stanford.edu/...nfo/references
It seems that the idea of an alias is some academic's way of
coming up with a concept that is easier to understand than
'ptr'.
Actually I would think, but I could be wrong, that the idea
comes from TC++PL where it says in §5.5 (freely translated
from Swedish) "A reference is an alternative name for an
object." But then again, BS is an academic.
Now. He wasn't when he wrote TC++PL. From the introduction to
references in the first edition of TC++PL: "A reference acts as
a name for an object". This is copyright 1986---more than 15
years, I think, before Stroustrup moved from Bell Labs to Texas
A&M. Whatever else one may say about it, C++ is firmly grounded
in pragmatic practice, and is not a product of "academica".

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Dec 30 '07 #33
On Dec 30, 1:52*pm, James Kanze <james.ka...@gmail.comwrote:
On Dec 27, 12:49 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-12-27 02:19, johanatan wrote:
On Dec 26, 6:33 am, Erik Wikström <Erik-wikst...@telia.comwrote:
>On 2007-12-26 06:01, johanatan wrote:
On Dec 25, 3:00 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
>Foo& Bar( int Val )
>{
>* *return Foo( Val );
>}
>Will not work, can not convert Foo to Foo&
Should work, but not a very useful thing to do as local
copy dies immediately.
>Should not work, a reference can not bind to a rvalue.
Ok, you're right. *I just tried this again in Ch (a C++
interpreter) -- apparently the method wasn't being called
before and so wasn't compiled.
>Does not work, same thing, can not convert Foo to Foo&.
Should also work. *Something else is going on as that
syntax is compiling fine in my compiler.
>Get a new compiler. Once again, you can not bind a
>reference to a rvalue.
This is certainly an interesting design decision of C++. *I
suspect it was a 'safety' feature built in, but I prefer
languages to be more flexible by inferring as much as
possible from context. *What is the danger of binding to an
r-value?
Consider the following code:
int& r = 5;
r = 6;
If I can bind a reference to a value I can also change that
value. But that is not how a reference works, a reference is a
alias for an object not an object on its own. Therefore a
reference can not bind to a rvalue.

That's an interesting example, and a very good reason for not
allowing using an rvalue to initialize a reference. *Still, the
original language (pre-1988, roughly, so we're talking about a
very long time ago) did allow using an rvalue to initialize any
reference, with more or less the same semantics which currently
apply when an rvalue is used to initialize a reference to const.
The rule was changed because it was found, in practice, to be
too great a source of errors. *IMHO, the real problem is that
there are too many implicit conversions, and that the result of
an implicit conversion is an rvalue; the errors are typically
cases where an implicit conversion resulted in an rvalue when
the programmer expected an lvalue. *Things like:

* * void
* * increment( int& i )
* * {
* * * * ++ i ;
* * }

* * int
* * main()
* * {
* * * * unsigned x = 0 ;
* * * * increment( x ) ;
* * * * std::cout << x << std::endl ;
* * * * return 0 ;
* * }

which, of course, results in 0.
Ahh. That's very interesting. This is the kind of bkg info I was
interested in.

Thanks,
Jonathan
Dec 31 '07 #34
On Dec 30, 2:13*pm, jkherci...@gmx.net wrote:
johanatan wrote:
On Dec 29, 11:51*pm, jkherci...@gmx.net wrote:
My point
was that someone who knows how the inner parts work in practice will
be better able to make decisions than those who don't.
Anyone who thinks about references in terms of broken metaphors will make
worse decisions than someone who knows the precise rules.
It would be really nice if people would take my words for what they
say instead of what they want them to say or what they think they
say. *The point was that someone who knows the inner workings (as well
as the precise rules) is better able to make decisions than someone
who knows only the precise rules.

I do not engage in reading minds but only in reading what people write. Your
claim did read like so:

* someone who knows how the inner parts work in practice will
* be better able to make decisions than those who don't

and neither like this:

* someone who knows how the inner parts work and knows the precise rules
* will be better able to make decisions than those who don't.

nor like this:

* someone who knows how the inner parts work and knows the precise rules
* will be better able to make decisions than those who only know the rules.
I figured that both hypothetical persons knew what I referred to in an
earlier post as the 'black-box' view (i.e., and which you are
referring to as the precise rules). That was included at the bottom
of the post that introduced the Stanford quote and the suggestion that
they become a 'Java school' if hiding such details is really that
important.
Besides, if you read what you quote carefully, you will find that I did not
contradict you anyway. I just provided an additional point of view.
Well, your comment didn't include any sort of conjunction (such as
'and') so I suppose that led me to believe that the point was offered
in contrast to mine. I apologize if it wasn't intended that way.
With regard to your clarified position, I find that the situations where
knowledge of the inner workings of references (given a particular compiler
and in addition to knowledge of the rules from the standard) is useful in
decision making are rather limited (in fact, just about nothing comes to
mind). However, that might just be a lack of imagination and experience on
my part. Could you provide some examples for the kind of decision making
you are thinking of?
Well, the first and most obvious one that comes to mind is-- parameter
payloads (pushing and popping as little as possible thereby using as
little stack space as possible, for say, a recursive function though
not necessarily so). I've never had to do much of this in practice
either, but I think that the concepts of 'reference' and 'pointer' in
the abstract are still equivalent (a position supported by the first
sentence of the Wikipedia entry on 'hard links').

However, much of this debate has been about both 'conceptual' and
'technical' understandings of references. Surely, at least now, my
position on the conceptual part is understandable? And, in practice,
since at least some of the time a compiler will compile references to
pointers, the technical part should be understandable too. Whether
that 'white-box', technical info is useful or not is quite another
matter. I wouldn't say that any knowledge is *never* useful though.

Even though I haven't changed any previous held (abstract) positions
drastically through this discussion, I certainly have learned some
things (such as how the compiler can track references and use no
memory slots for holding them) so now my 'white-box' view is even
better than before.

Thanks,
Jonathan
Dec 31 '07 #35
On Dec 30, 5:09*pm, James Kanze <james.ka...@gmail.comwrote:
That just isn't true (on both technical and conceptual levels).
Technically, a reference in C++ is just a ptr with syntactic sugar to
allow using it just like the object itself instead of dereferencing
the ptr (or using the -operator).

Not really. *A C++ reference is a more or less an alias for an
object. *It can't be null, and it can't be reseated.
Ok, now I understand the term 'alias' a little more after seeing that
it describes those limitations of references a little better. But, as
with most CS concepts, alias can mean alot of different things in
different environments. Take bash shell scripts for instance, it's
just a way of 'rewriting' a command. Or, a string that represents
another string. Or, a symbol that refers to another symbol. Or, a
link. Or, a pointer. All these concepts at the abstract level seem
pretty equivalent.

And, if you want to start getting into the differences at the
technical level in any given environment, then you have to learn the
differences and the names are there simply to provide a common
vocabulary (but conceptually, do we always think in a language? What
is the essence of these concepts if you set aside the differences in
names?)

The name of something is not what matters, but its essence. Names are
only there to make communication easier (and with the 'attached'
conceptions to most names especially when going from one computer lang/
platform/lib to another they serve to confuse a great deal).
Comparisons with Java and C# don't make much sense, either,
because the object model is different: in C++, a pointer is an
object, just like an int or anything else, and you can take the
actual address of anything---in Java (and C#?), only class types
can be objects, you can only have a reference (or pointer) to a
class type, and all objects of class types must be dynamically
allocated. *Globally considered, references in Java are as exact
an equivalent to C++ pointers as you can have, given the object
model of Java.
Not really, references behave syntactically the same in C++ and Java
(except for the use of the &). Everything is by default a reference
in Java, and you can't get at the pointers. Maybe C# is a more
relevant example because with it, you can have an 'unsafe' block and
still get to the actual underlying pointers. But, in my mind, a
reference in all 3 langs is essentially the same.
-. Java references are 'smart' references (i.e., ref counted).

Not in any Java implementation I've seen or heard of.
Actually, they are smart. But, I was mistaken about the ref-counted
part. The garbage collector traverses all 'live' ptrs and deletes
those that it doesn't reach.
-. Java references can be assigned to NULL.

Like C++ pointers.
-. Java references can be set multiple times (and have no
restrictions against setting to r-values).

Java doesn't have rvalues, at least, not in the sense C++ does.
What about this piece of code:

foo f1;
foo f2;

someFunc(f1 + f2);

f1 + f2 is an r-value and it can be passed directly to someFunc
assuming that it accepts foo or object types.
In C++, a pointer can be set multiple times, as in Java. *And
you need to jump through hoops to get it to point to an rvalue,
since you cannot directly take the address of an rvalue (and of
course, an object allocated by new is not an rvalue).

So far, you've shown that references in Java are the equivalent
of pointers in C++, not the equivalent of references.
No, references in Java are very different from pointers. You can't
actually modify a reference except by setting it equal to another
object or null. The underlying ptr is inaccessible. You also cannot
use multiple levels of indirection with Java references. There is no
& (address) operator in Java as you never need to worry about
addresses. The reference abstracts that away. Much the same way a C+
+ reference does.
No. *I think that the original motivation for references in C++
is linked with operator overloading; they allow writing an
operator+ which doesn't require a deep copy of both of its
arguments, but can still be called with the usual syntax. *The
designers of Java based there references on C++ (and C)
pointers, simply eliminating features which they felt were too
dangerous (like pointer arithmetic) or which didn't fit into the
object model. *(For that matter, pointer arithmetic really
wouldn't fit into the Java object model either.) *The choice of
the name was purely based on the supposed reputation that
pointers were dangerous, and that in a "safe" language, you
can't have pointers. *(Marketing, in sum.)
Well, I think we agree on most of that except that refs allow you to
prevent deep copy on many other overloaded operators too (copy
constructor, etc) and whatever custom code you want to write to pass
something 'by reference'. So I find it hard to believe that operator+
was the sole or even primary motivation. Also, It is very hard to
convince me that the word reference was chosen completely
independantly of the notion of 'passing something by reference' in C
(which was done with ptrs).

The other difference we have is that I think that Java designers chose
the word 'reference' exactly because of the semantics of reference in C
++, but simply cleaned it up a bit and added features to it. It
certainly feels a lot more like a C++ reference than a C++ pointer
simply because you don't have to dereference or use the -operator
(and you can use the . operator).

The reference in C++ was supposed to be an improvement over pointers.
But, since it kept pointers for backwards compatibility with C, it
couldn't universally use refs. Java didn't have that problem so could
add what was needed to reference (namely setting to NULL and allowing
resets) and therby improve upon the C++ notion of reference.

When you have two ways of doing something, you have to figure out how
to limit each way (or else they both simply become exact clones).
But, if there's only one way, you can implement the minimal featureset
(and produce a cleaner design IMHO). And, the fact that the designers
of Java named it 'reference' instead of 'pointer' seems to be
indicative which of the two ideas they thought it was more similar to.

--Jonathan
Dec 31 '07 #36
On 2007-12-31 07:00, johanatan wrote:
On Dec 30, 5:09 pm, James Kanze <james.ka...@gmail.comwrote:
-. Java references can be set multiple times (and have no
restrictions against setting to r-values).

Java doesn't have rvalues, at least, not in the sense C++ does.

What about this piece of code:

foo f1;
foo f2;

someFunc(f1 + f2);

f1 + f2 is an r-value and it can be passed directly to someFunc
assuming that it accepts foo or object types.
According to the Java Language Specification 3rd ed. §15.1:

When an expression in a program is evaluated (executed), the result
denotes one of three things:
• A variable (§4.12) (in C, this would be called an lvalue)
• A value (§4.2, §4.3)
• Nothing (the expression is said to be void)

A value is of course something of value-type (int, double etc.) and
while they are not like lvalues they are not rvalues either.

--
Erik Wikström
Dec 31 '07 #37
On Dec 31, 12:25 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-12-31 07:00, johanatan wrote:
On Dec 30, 5:09 pm, James Kanze <james.ka...@gmail.comwrote:
-. Java references can be set multiple times (and have no
restrictions against setting to r-values).
Java doesn't have rvalues, at least, not in the sense C++ does.
What about this piece of code:
foo f1;
foo f2;
someFunc(f1 + f2);
f1 + f2 is an r-value and it can be passed directly to someFunc
assuming that it accepts foo or object types.
According to the Java Language Specification 3rd ed. §15.1:
When an expression in a program is evaluated (executed), the result
denotes one of three things:
? A variable (§4.12) (in C, this would be called an lvalue)
? A value (§4.2, §4.3)
? Nothing (the expression is said to be void)
And that parenthese is the only use of either lvalue or rvalue
that I know of in the entire specification. It's interesting,
because it means that an expression like a[i] is a "variable";
we wouldn't consider it a variable in C/C++. Different
languages, different philosophies, different basic models, and a
different vocabulary. (But both do use { and }... two
characters which aren't present on my local keyboards.)
A value is of course something of value-type (int, double
etc.) and while they are not like lvalues they are not rvalues
either.
Note that in Java, you cannot take the address of either a value
or a "variable". In a very real sense, neither has an address;
only objects have addresses.

As I've already said, the object model is completely different,
so trying to push analogies isn't going to work.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Dec 31 '07 #38
On Dec 31, 3:25 am, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-12-31 07:00, johanatan wrote:
On Dec 30, 5:09 pm, James Kanze <james.ka...@gmail.comwrote:
-. Java references can be set multiple times (and have no
restrictions against setting to r-values).
Java doesn't have rvalues, at least, not in the sense C++ does.
What about this piece of code:
foo f1;
foo f2;
someFunc(f1 + f2);
f1 + f2 is an r-value and it can be passed directly to someFunc
assuming that it accepts foo or object types.

According to the Java Language Specification 3rd ed. §15.1:

When an expression in a program is evaluated (executed), the result
denotes one of three things:
* A variable (§4.12) (in C, this would be called an lvalue)
* A value (§4.2, §4.3)
* Nothing (the expression is said to be void)

A value is of course something of value-type (int, double etc.) and
while they are not like lvalues they are not rvalues either.
So, does that mean that an expression cannot evaluate to a reference
to an object? Even if operator overloading is prohibited, there are
other expressions that could result in a 'reference' to an object as
the result.

--Jonathan
Jan 1 '08 #39
On 2007-12-31 21:36:09 -0500, johanatan <jo*******@gmail.comsaid:
[...]
The 'historical' understanding I had was certainly somewhat fabricated
and falsely
extrapolated, but I think we all agree that the abstract notions of
ptrs, references, and aliases are essentially the same and could
probably offer examples of lots of different languages where this or
that aspect is this or that way. That doesn't change the fact that I
can still *think* of them in the abstract as essentially equivalent
concepts. :-)
Comment like this is prime example of what has become known as "truthiness."

http://en.wikipedia.org/wiki/Truthiness

--

-kira

Jan 1 '08 #40
On Jan 1, 3:38 am, johanatan <johana...@gmail.comwrote:
On Dec 31, 3:25 am, Erik Wikström <Erik-wikst...@telia.comwrote:
According to the Java Language Specification 3rd ed. §15.1:
When an expression in a program is evaluated (executed), the result
denotes one of three things:
* A variable (§4.12) (in C, this would be called an lvalue)
* A value (§4.2, §4.3)
* Nothing (the expression is said to be void)
A value is of course something of value-type (int, double etc.) and
while they are not like lvalues they are not rvalues either.
So, does that mean that an expression cannot evaluate to a
reference to an object?
Just the opposite. An expression in Java never evaluates to an
object type, only to a variable or a value. Variables and
values can have either a basic type or a reference type; they
are never objects.

Again: the object model in Java is radically different than that
in C++, so any analogies are likely to be misleading.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 1 '08 #41
On Dec 31 2007, 10:17*pm, Kira Yamato <kira...@earthlink.netwrote:
On 2007-12-31 21:36:09 -0500, johanatan <johana...@gmail.comsaid:
[...]
The 'historical' understanding I had was certainly somewhat fabricated
and falsely
extrapolated, but I think we all agree that the abstract notions of
ptrs, references, and aliases are essentially the same and could
probably offer examples of lots of different languages where this or
that aspect is this or that way. *That doesn't change the fact that I
can still *think* of them in the abstract as essentially equivalent
concepts. :-)

Comment like this is prime example of what has become known as "truthiness.."

http://en.wikipedia.org/wiki/Truthiness

--
Well, if you want to get that personal, I guess I'll continue
defending myself (though I do not really need to). I highly suspect
that everyone does just this. No one has the time to exhaustively
research each and every detail of their view of the world (let alone
the histories of those views). So, we extrapolate and fill in the gaps
with somewhat speculative information. Are you saying you don't do
the same?

And, furthermore, my views actually were not all that historically
incorrect. If you want, we can get back to the original discussion.
I still do not accept that references are merely 'aliases'. If
anything, the word alias is just as flawed as pointer. A reference is
a reference. I think that's the point that people are drive home.
You have to look at the C++ standard and look at how it defines
'reference.'

Take these two examples:

int x;
int& y;

Yes, in that case, everyone agrees. That's what feels to me like an
'alias'.

But, what about this (somewhat more complex example):

void f(int& x)
{
x = 9;
}

void g(int& y)
{
y = 7;
}

int main()
{
int x = 3;
f(g(x));
}

and really it would help to make the call stack 10 or more levels
deep. There's no way you're going to implement that without using
'pointers'. If anyone can think of such a way, please do share.

Given the close ties between C and C++, it is not unreasonable at all
to think of references as pointers. You can try to indoctrinate the
new students with this notion of 'alias', but it's going to be hard to
erase the memory of pointers from C or assembly programmers.

That's all.
Jan 12 '08 #42
On Jan 1, 4:38*am, James Kanze <james.ka...@gmail.comwrote:
On Jan 1, 3:38 am, johanatan <johana...@gmail.comwrote:
On Dec 31, 3:25 am, Erik Wikström <Erik-wikst...@telia.comwrote:
According to the Java Language Specification 3rd ed. §15.1:
* When an expression in a program is evaluated (executed), the result
* denotes one of three things:
* * * A variable (§4.12) (in C, this would be called an lvalue)
* * * A value (§4.2, §4.3)
* * * Nothing (the expression is said to be void)
A value is of course something of value-type (int, double etc.) and
while they are not like lvalues they are not rvalues either.
So, does that mean that an expression cannot evaluate to a
reference to an object?

Just the opposite. *An expression in Java never evaluates to an
object type, only to a variable or a value. *Variables and
values can have either a basic type or a reference type; they
are never objects.
Well, given that the 'variables' in Java (which are not values, or
intrinsics) are 'references' (usually to objects), I'd say I'm a
little confused by your remark. Would you mind to please clarify?
Jan 12 '08 #43
johanatan wrote:
But, what about this (somewhat more complex example):

void f(int& x)
{
x = 9;
}

void g(int& y)
{
y = 7;
}

int main()
{
int x = 3;
f(g(x));
}
No problem, this example wouldn't compile. g returns void (or, more
properly, doesn't return a value), so you can't pass g(x) to f().
Jan 12 '08 #44
On Jan 11, 8:31*pm, red floyd <no.s...@here.dudewrote:
johanatan wrote:
But, what about this (somewhat more complex example):
void f(int& x)
{
* x = 9;
}
void g(int& y)
{
* y = 7;
}
int main()
{
* int x = 3;
* f(g(x));
}

No problem, this example wouldn't compile. *g returns void (or, more
properly, doesn't return a value), so you can't pass g(x) to f().
Ooops. Sorry. Meant this:

int main()
{
int x = 9;
f(x);
g(x);
}
Jan 12 '08 #45
On Jan 11, 8:31*pm, johanatan <johana...@gmail.comwrote:
On Jan 1, 4:38*am, James Kanze <james.ka...@gmail.comwrote:
On Jan 1, 3:38 am, johanatan <johana...@gmail.comwrote:
On Dec 31, 3:25 am, Erik Wikström <Erik-wikst...@telia.comwrote:
According to the Java Language Specification 3rd ed. §15.1:
* When an expression in a program is evaluated (executed), the result
* denotes one of three things:
* * * A variable (§4.12) (in C, this would be called an lvalue)
* * * A value (§4.2, §4.3)
* * * Nothing (the expression is said to be void)
A value is of course something of value-type (int, double etc.) and
while they are not like lvalues they are not rvalues either.
So, does that mean that an expression cannot evaluate to a
reference to an object?
Just the opposite. *An expression in Java never evaluates to an
object type, only to a variable or a value. *Variables and
values can have either a basic type or a reference type; they
are never objects.
If variables can have a 'reference type', then the answer to my
question would be 'yes'. Noticed I asked if an expression could
evaluate to a 'reference to an object'. This is what you seem to be
referring to as a 'variable which happens to be a reference'. But, in
my simplistic world, I just call a variable that happens to be a
reference, or 'has a reference type' as you say, 'references' (and
sometimes if I'm feeling a little verbose, I might say 'reference to
an object'.

Would you say that an object in the real world that has the type of
car is a car? Or does it just have the type of car? This is probably
a philosophical question, but to simple me, it *is* a car.

--Jonathan
Jan 12 '08 #46
On Jan 11, 8:34*pm, johanatan <johana...@gmail.comwrote:
On Jan 11, 8:31*pm, red floyd <no.s...@here.dudewrote:
johanatan wrote:
But, what about this (somewhat more complex example):
void f(int& x)
{
* x = 9;
}
void g(int& y)
{
* y = 7;
}
int main()
{
* int x = 3;
* f(g(x));
}
No problem, this example wouldn't compile. *g returns void (or, more
properly, doesn't return a value), so you can't pass g(x) to f().

Ooops. *Sorry. *Meant this:

int main()
{
* int x = 9;
* f(x);
* g(x);

}
And, actually, my first 'simple' example had a little problem too.
Meant this:

int x;
int& y = x;

but, everyone probably 'extrapolated' that (hopefully truthily (it's a
joke, i don't really think there's such a word)).

--Jonathan
Jan 12 '08 #47
On Jan 11, 9:21*pm, "Alf P. Steinbach" <al...@start.nowrote:
I think the only way to really say what influenced the C++ reference
would be to ask the designer himself.

I'm pretty sure this is explained in his "evolution" book, although I
don't have that book. *You might also look in Bjarne's FAQ. *I'm not
sure, but there's a good chance it's covered there too.
*Hypothesizing that lang X or
lang Y which had a concept of 'pointer' or 'reference' as the main
motivation for the C++ reference is overlooking the 800 lb. gorilla
(who happens to have almost the same name except for those two plus
signs) and is by anyone's account a *huge* influence. *How can a
servant be greater than his master?

Presumably you're talking about C.
Yea, specifically, I was responding to the claim that C++ borrowed the
idea of a reference from the Algol67 or some such language. The more
I think about this discussion, the more it is apparent to me that
these following words are 'synonyms' in the abstract (i.e., aside from
specific implementations):

handle, pointer, address, reference, alias, moniker.

And, I'm sure there are more I'm forgetting right now. This page on
references is quite illuminating:

http://en.wikipedia.org/wiki/Referen...ter_science%29

It says that even in compiled, functional languages, such as Standard
ML and O'Caml, references are usually implemented as 'pointers' under
the hood. And, in Java, C#, and the like, they are implemented as
'two-step pointers' or doubly-indirected pointers.
The main motivation for C++ references was to support operator
overloading and more generally implementing types and functions on a par
with built-in types and functions.
That's interesting. Though, I would still venture to say that the
motivation for the name of the construct of the C++ reference would be
the formal CS literature which the Wiki page I 'referenced' above
summarizes. And, I would think that it would be very hard for someone
already well-versed in C and assembly and most likely the writing of
compilers for both C and C++ to suddenly forget how references could
or even should be implemented. And, also, at this point, if they were
to come up with some different conception of a reference, they would
need to forget the notion of 'call-by-reference' which was very well
established practice in C (and even asm).

The question of which language(s) aside from C 'inspired' the C++
reference is just a red herring. Many languages have a concept of
'reference' and they all get the notion from 'pure' CS literature.
The fact is, he could have chosen any of the above synonyms, but he
didn't, he chose a 'loaded' word which would immediately conjure up
images from other contexts (and also, it just so happens to be the
word that is the most general for this concept in the pure CS
literature). It is the word that is least attached to a specific
implementation. So, to summarize, he could have chosen it for 2
reasons (and I suspect both):

1 - C and assembly connotations
2 - purest name of a CS concept that can be described by a number of
competing names all of which carry more specific connotations (or did
at the time C++ was written)

The name pointer was taken directly from C, and the new construct was
the first time a new name had to be given to that concept in C++ (at
least we don't have 3 types of references, pointers, aliases, do
we?). It makes most sense to go with 'purest CS' and the added C
connotations are just a bonus since C++ programmers should already be
well familiar with C and assembly.

That's my 'constructed' historical view. It that's someone
inaccurate, please do shed light.

--Jonathan
Jan 12 '08 #48
On Jan 11, 10:42*pm, johanatan <johana...@gmail.comwrote:
On Jan 11, 9:21*pm, "Alf P. Steinbach" <al...@start.nowrote:
I think the only way to really say what influenced the C++ reference
would be to ask the designer himself.
I'm pretty sure this is explained in his "evolution" book, although I
don't have that book. *You might also look in Bjarne's FAQ. *I'm not
sure, but there's a good chance it's covered there too.
*Hypothesizing that lang X or
lang Y which had a concept of 'pointer' or 'reference' as the main
motivation for the C++ reference is overlooking the 800 lb. gorilla
(who happens to have almost the same name except for those two plus
signs) and is by anyone's account a *huge* influence. *How can a
servant be greater than his master?
Presumably you're talking about C.

Yea, specifically, I was responding to the claim that C++ borrowed the
idea of a reference from the Algol67 or some such language. *The more
I think about this *discussion, the more it is apparent to me that
these following words are 'synonyms' in the abstract (i.e., aside from
specific implementations):

handle, pointer, address, reference, alias, moniker.

And, I'm sure there are more I'm forgetting right now. *This page on
references is quite illuminating:

http://en.wikipedia.org/wiki/Referen...ter_science%29

It says that even in compiled, functional languages, such as Standard
ML and O'Caml, references are usually implemented as 'pointers' under
the hood. *And, in Java, C#, and the like, they are implemented as
'two-step pointers' or doubly-indirected pointers.
The main motivation for C++ references was to support operator
overloading and more generally implementing types and functions on a par
with built-in types and functions.

That's interesting. *Though, I would still venture to say that the
motivation for the name of the construct of the C++ reference would be
the formal CS literature which the Wiki page I 'referenced' above
summarizes. *And, I would think that it would be very hard for someone
already well-versed in C and assembly and most likely the writing of
compilers for both C and C++ to suddenly forget how references could
or even should be implemented. *And, also, at this point, if they were
to come up with some different conception of a reference, they would
need to forget the notion of 'call-by-reference' which was very well
established practice in C (and even asm).

The question of which language(s) aside from C 'inspired' the C++
reference is just a red herring. *Many languages have a concept of
'reference' and they all get the notion from 'pure' CS literature.
The fact is, he could have chosen any of the above synonyms, but he
didn't, he chose a 'loaded' word which would immediately conjure up
images from other contexts (and also, it just so happens to be the
word that is the most general for this concept in the pure CS
literature). *It is the word that is least attached to a specific
implementation. *So, to summarize, he could have chosen it for 2
reasons (and I suspect both):

1 - C and assembly connotations
2 - purest name of a CS concept that can be described by a number of
competing names all of which carry more specific connotations (or did
at the time C++ was written)

The name pointer was taken directly from C, and the new construct was
the first time a new name had to be given to that concept in C++ (at
least we don't have 3 types of references, pointers, aliases, do
we?). *It makes most sense to go with 'purest CS' and the added C
connotations are just a bonus since C++ programmers should already be
well familiar with C and assembly.

That's my 'constructed' historical view. *It that's someone
inaccurate, please do shed light.
P.S. I would also add that the 'pure CS' literature probably borrowed
the idea from philosophy (Plato, Aristotle or some such) so if we
really want to take this debate much further, we probably need to
change groups.
Jan 12 '08 #49
On Jan 12, 6:21 am, "Alf P. Steinbach" <al...@start.nowrote:
* johanatan:
I think the only way to really say what influenced the C++ reference
would be to ask the designer himself.
I'm pretty sure this is explained in his "evolution" book, although I
don't have that book.
It is. That's where I got the information that he was
influenced by Algol from.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 12 '08 #50

This thread has been closed and replies have been disabled. Please start a new discussion.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.