Returning a reference from a function.

R

ravi

Can anybody out there tell me whether it i possible to return a
reference from a function in C++

I am using Turbo C++
 
Z

Zeppe

ravi said:
Can anybody out there tell me whether it i possible to return a
reference from a function in C++

I am using Turbo C++

yes, it is possible, if the object whose reference is being returned is
not local. For example:

int& increment(int& a)
{
a+1;
return a;
}

Regards,

Zeppe
 
L

Lionel B

yes, it is possible, if the object whose reference is being returned is
not local. For example:

int& increment(int& a)
{
a+1;

Did you mean a += 1 ? (not that it matters)
return a;
}

Of course it's also *possible* (i.e. permitted by the language) - but
quite likely disastrous! - if the returned reference *is* to a local
object:

int& foo()
{
int a;
return a;
}

int main()
{
}

$ g++ -std=c++98 -pedantic scratch.cpp
scratch.cpp: In function ‘int& foo()’:
scratch.cpp:3: warning: reference to local variable ‘a’ returned

(note warning, but no error).
 
L

Lionel B

On Thu, 12 Jul 2007 17:09:47 +0300, Juha Nieminen wrote:

(snipped context restored)
Why is it not an error?

Because the Standard says it's not. I can't think off the top of my head
a valid scenario for doing this (no doubt someone here can...), but there
you go... C++ is renowned for supplying plenty of rope to hang yourself.
 
F

Fred Kleinschmidt

Juha Nieminen said:
Why is it not an error?

Some compilers try to be helpful and distinguish between
what the compiler thinks will be fatal and what it thinks
might not be fatal, but is a mistake nonetheless.

However, this behavior is not required by the standard -
the standard only requires that a message be output.
It makes no distinction between "error" and "warning".
 
A

Alf P. Steinbach

* Lionel B:
On Thu, 12 Jul 2007 17:09:47 +0300, Juha Nieminen wrote:

(snipped context restored)


Because the Standard says it's not. I can't think off the top of my head
a valid scenario for doing this (no doubt someone here can...),

Well, one usage is to compute a stack pointer. Which might be used to
decide whether some object is allocated on the stack or not. Conceivably...
 
M

Massimo Burcheri

Juha said:
Why is it not an error?

Because it references a local variable that has existed. After the function
the variable is freed and the referenced data is uncertain, most probably
will make your application crash.

Massimo
 
J

James Kanze

Because the Standard says it's not. I can't think off the top
of my head a valid scenario for doing this (no doubt someone
here can...), but there you go... C++ is renowned for
supplying plenty of rope to hang yourself.

The reason the standard says it doesn't require a diagnostic is
because it's impossible to determine in all cases. The standard
doesn't have too many options: if it's an error (it is), then it
is either undefined behavior, or a diagnostic is required. And
since it is impossible for a compiler to generate the diagnostic
in every case...
 
L

Lionel B

The reason the standard says it doesn't require a diagnostic is because
it's impossible to determine in all cases.
Ok.

The standard doesn't have too many options: if it's an error (it is),

I think myself (and the OP) were using "error" as in "illegal code -
shouldn't compile"... at least that's what my compiler seems to call an
"error".
then it is either undefined behavior,

It is.
or a diagnostic is required. And since it is impossible for a
compiler to generate the diagnostic in every case...

....it might at least do so when it can, as it does in my example.
 
J

Juha Nieminen

James said:
The reason the standard says it doesn't require a diagnostic is
because it's impossible to determine in all cases. The standard
doesn't have too many options: if it's an error (it is), then it
is either undefined behavior, or a diagnostic is required. And
since it is impossible for a compiler to generate the diagnostic
in every case...

When the compiler compiles a 'return' statement it has to know
what is being returned, naturally.
The compiler also sees all the local variables and, if necessary,
destroys them (calls destructors, etc) alongside the 'return'.
Thus it would sound trivial for the compiler to check if the
returned reference is pointing to a local variable which is destroyed
before the function is exited. It doesn't make sense to return a
reference to something which is being destroyed in the very same
statement!
 
R

Robert Bauck Hamar

Juha said:
When the compiler compiles a 'return' statement it has to know
what is being returned, naturally.
The compiler also sees all the local variables and, if necessary,
destroys them (calls destructors, etc) alongside the 'return'.
Thus it would sound trivial for the compiler to check if the
returned reference is pointing to a local variable which is destroyed
before the function is exited. It doesn't make sense to return a
reference to something which is being destroyed in the very same
statement!

If it is as simple as that, yes. Assume:

class foo {
int x;
public:
foo(int x) : x(x) {}
int& ref();
}

// definition of foo::ref compiled in one translation unit

int& foo::ref()
{ return x; }

// in some other translation unit:

int& bar() {
foo f;
return f.ref();
}

While compiling bar, the compiler cannot possibly know that f.ref() is
destroyed with f. This is a case where the compiler cannot determine. Of
course the standard could have made a separate rule about local objects,
but it doesn't. This is up to the vendors, who are competing to make good
compilers.
 
J

James Kanze

When the compiler compiles a 'return' statement it has to know
what is being returned, naturally.

But it can't know whether that what is a reference to a local
variable or not.
The compiler also sees all the local variables and, if necessary,
destroys them (calls destructors, etc) alongside the 'return'.
Thus it would sound trivial for the compiler to check if the
returned reference is pointing to a local variable which is destroyed
before the function is exited. It doesn't make sense to return a
reference to something which is being destroyed in the very same
statement!

The compiler knows it is returning a reference. It doesn't
necessarily know to what. If it is binding the reference to a
local variable in the return statement, it can warn; many do.
But what about things like:

int&
f( bool condition, int& x )
{
static int y = 42 ;
return condition ? x : y ;
}

int&
g( bool condition )
{
int x = 3 ;
return f( condition, x ) ;
}

Whether the reference is bound to a local variable depends on
the value of condition, which the compiler cannot possibly know.
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top