www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What on earth is a ref function?

reply simendsjo <simen.endsjo pandavre.com> writes:
The spec is very short here, and the example doesn't give me much..

// I thought "allows functinos to return by reference" meant it could 
return local variables..
ref int* ptr() {
	auto p = new int;
	*p = 12;
	return p; // Error: escaping local variable
}

// So whats the difference between these functions?

ref int val() {
	auto p = new int;
	assert(*p == 0);
	*p = 10;
	assert(*p == 10);
	return *p;
}

int val2() {
	auto p = new int;
	*p = 10;
	return *p;
}

unittest
{
	assert(val() == 10);
	assert(val2() == 10);
	auto retvalue = val() = 99; // References can be lvalues.. What?
	assert(retvalue == 99);
}
Aug 08 2010
next sibling parent BCS <none anon.com> writes:
Hello simendsjo,

 The spec is very short here, and the example doesn't give me much..
 
 // I thought "allows functinos to return by reference" meant it could
 return local variables..
 ref int* ptr() {
 auto p = new int;
 *p = 12;
 return p; // Error: escaping local variable
 }
 // So whats the difference between these functions?
 

Just guessing but I'd guess that acts much like C++'s ref: int*& Fn() { ... } // return a reference to a pointer to an int.
 ref int val() {
 auto p = new int;
 assert(*p == 0);
 *p = 10;
 assert(*p == 10);
 return *p;
 }

Return a reference to an int (that is also pointed to by a local variable) who's value is 10
 int val2() {
 auto p = new int;
 *p = 10;
 return *p;
 }

Return the value (10) of an int that is pointed to by a local variable.
 unittest
 {
 assert(val() == 10);
 assert(val2() == 10);
 auto retvalue = val() = 99; // References can be lvalues.. What?

The main point of references is that they can be lvalues.
 assert(retvalue == 99);
 }

... <IXOYE><
Aug 08 2010
prev sibling next sibling parent Mike Parker <aldacron gmail.com> writes:
simendsjo wrote:
 The spec is very short here, and the example doesn't give me much..
 
 // I thought "allows functinos to return by reference" meant it could 
 return local variables..
 ref int* ptr() {
     auto p = new int;
     *p = 12;
     return p; // Error: escaping local variable
 }
 

For free functions, it's useful for returning references to module or global scope variables. Though what the use-case for that would be, I don't know off the top of my head. In C++, it's a common idiom for class methods to return references, rather than pointers, to class members in certain situations.
Aug 08 2010
prev sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
simendsjo <simen.endsjo pandavre.com> wrote:

 The spec is very short here, and the example doesn't give me much..

 // I thought "allows functinos to return by reference" meant it could  
 return local variables..
 ref int* ptr() {
 	auto p = new int;
 	*p = 12;
 	return p; // Error: escaping local variable
 }

This fails because p itself is stack allocated. By reference means it returns a hidden pointer to something. Because this is a pointer, you can get the address of the returned value, and do things to it.
 // So whats the difference between these functions?

 ref int val() {
 	auto p = new int;
 	assert(*p == 0);
 	*p = 10;
 	assert(*p == 10);
 	return *p;
 }

This returns what is in effect p - a pointer (reference) to an int.
 int val2() {
 	auto p = new int;
 	*p = 10;
 	return *p;
 }

This returns simply the value of *p.
 unittest
 {
 	assert(val() == 10);
 	assert(val2() == 10);
 	auto retvalue = val() = 99; // References can be lvalues.. What?
 	assert(retvalue == 99);
 }

Giving an example of what one can do with a reference: ref int foo( ref int val ) { return ++value; } int n = 3; foo( n ) = 4; assert( n == 4 ); assert( foo( n ) == 5 ); -- Simen
Aug 09 2010