Thread overview
What on earth is a ref function?
Aug 08, 2010
simendsjo
Aug 08, 2010
BCS
Aug 09, 2010
Mike Parker
Aug 09, 2010
Simen kjaeraas
August 08, 2010
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);
}
August 08, 2010
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><



August 09, 2010
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.
August 09, 2010
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