Construction of function return value

M

Michael Klatt

class Foo
{
public :
explicit Foo(int i) : m_int(i) {}

private :
int m_int;
};

Foo f(int i)
{
return i;
}

Foo g(int i);
{
return Foo(i);
}

int main()
{
f(2); // is a Foo ever constructed?
}



Will a Foo be constructed by the return statement in f() even if the
return value is ignored in the calling function or does the
constructor have to be explicitly called as in g()?
 
E

E. Robert Tisdale

Michael Klatt wrote:

[snip]
cat foo.cc
class Foo {
private :
int m_int;
public:
explicit Foo(int i): m_int(i) { }
};

Foo f(int i) {
return i;
}

Foo g(int i) {
return Foo(i);
}

int main(int argc, char* argv[]) {
f(2); // Is a Foo ever constructed?
return 0;
}
g++ -Wall -ansi -pedantic -o foo foo.cc
foo.cc: In function `Foo f(int)':
foo.cc:9: error: \
conversion from `int' to non-scalar type `Foo' requested
Will a Foo be constructed by the return statement in f()
No.

even if the return value is ignored in the calling function
or does the constructor have to be explicitly called as in g()?

Yes because it is an *explicit* constructor.
 
A

Ali Cehreli

Michael Klatt said:
class Foo
{
public :
explicit Foo(int i) : m_int(i) {}

private :
int m_int;
};

Foo f(int i)
{
return i;

If the above compiles, it's a compiler bug. Are you using VC++6.0? This is a
known bug in that compiler.
}

Foo g(int i);
{
return Foo(i);

This is the right way of returning an object with an 'explicit' constructor.
}

int main()
{
f(2); // is a Foo ever constructed?
}



Will a Foo be constructed by the return statement in f() even if the
return value is ignored in the calling function or does the
constructor have to be explicitly called as in g()?

I am not sure about the answer to this one. (?) I believe though, if the
constructor and/or the destructor of Foo has side effects, I don't think the
compiler has the right to elide the construction.

Ali
 
R

Rob Williscroft

Michael Klatt wrote in
in comp.lang.c++:
class Foo
{
public :
explicit Foo(int i) : m_int(i) {}

private :
int m_int;
};

Foo f(int i)
{

Did you try compiling, you should get a invalid conversion or
similar error here, Foo only has an explict ctor.
return i;
}

Foo g(int i);
{
return Foo(i);
}

int main()
{
f(2); // is a Foo ever constructed?
}



Will a Foo be constructed by the return statement in f()

It won't compile.
even if the
return value is ignored in the calling function

Return values are constructed by the the function that is
returning them, wether or not the caller uses the value
doesn't matter.
or does the
constructor have to be explicitly called as in g()?

If Foo::Foo( int ) wasn't explicit then f() would compile
and both it and g() would be equivalent.

Rob.
 
D

DaKoadMunky

Return values are constructed by the the function that is
returning them, wether or not the caller uses the value
doesn't matter.

Given the following...

class SomeClass
{
public:

SomeClass()
{
}

SomeClass& operator=(const SomeClass&)
{
return *this;
}

private:

SomeClass(const SomeClass&)
{
}
};

SomeClass SomeFunction()
{
SomeClass sc;
return sc; //Produces error because of inaccessible copy constructor
}

int main()
{
SomeClass sc;
sc = SomeFunction(); //Produces error because of inaccessible copy
constructor
}

I can see why an error is produced in SomeFunction() because it is attempting
to invoke a copy constructor that is inacessible.

Why though does the code in function main() result in an error? I don't see
how it is that the copy constructor is involved within that function.

Thanks
 
G

Gregg

(e-mail address removed) (DaKoadMunky) wrote in
Given the following...

class SomeClass
{
public:

SomeClass()
{
}

SomeClass& operator=(const SomeClass&)
{
return *this;
}

private:

SomeClass(const SomeClass&)
{
}
};

SomeClass SomeFunction()
{
SomeClass sc;
return sc; //Produces error because of inaccessible copy
constructor
}

int main()
{
SomeClass sc;
sc = SomeFunction(); //Produces error because of inaccessible copy
constructor
}

I can see why an error is produced in SomeFunction() because it is
attempting to invoke a copy constructor that is inacessible.

Why though does the code in function main() result in an error? I
don't see how it is that the copy constructor is involved within that
function.

The statement

SomeClass sc

creates a fully constructed object. It is not like Java where it would
create only a reference to one that has yet to exist. Then the statement

sc = SomeFunction()

reassigns sc the new one returned by SomeFunction.

Gregg
 
R

Rob Williscroft

DaKoadMunky wrote in in comp.lang.c++:
I can see why an error is produced in SomeFunction() because it is
attempting to invoke a copy constructor that is inacessible.

Why though does the code in function main() result in an error? I
don't see how it is that the copy constructor is involved within that
function.

The function return's an rvalue, however the assignment operator takes
a constant lvalue (const &). This conversion from rvalue to constant
lvalue symanticly requires the creation of a temporary (which can
be an lvalue).

Its the construction of the temporary that requires an accesable
copy-constructor.

Implementation's are allowed to eleminate the creation of the
temporary (as an optimisation), but they aren't allowed to drop
the accesable copy-constructor requirement.

Hence the error message in main().

Rob.
 
J

JKop

Why though does the code in function main() result in an error? I
don't see how it is that the copy constructor is involved within that
function.

Thanks

Whenever you return an object from a function by value, as
in:

#include <iostream>

std::string Blah()
{
return std::string("Hello!");
}

Then the copy constructor needs to be public, as the
function must have the choice of copying the object before
returning it, (which most won't do).

-JKop
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,176
Messages
2,570,947
Members
47,501
Latest member
Ledmyplace

Latest Threads

Top