I've simple class method like
Task TaskSample::Create(void)
{
Task task;
return task;
}
and got warning taking address of temporary. Is something wrong with this code ? I prefer to not use pointer here
I've simple class method like
Task TaskSample::Create(void)
{
Task task;
return task;
}
and got warning taking address of temporary. Is something wrong with this code ? I prefer to not use pointer here
If that is actually what your code is, then the compiler is probably in error.
More likely, however, you actually wrote this:
Task& TaskSample::Create(void)
{
Task task;
return task;
}
Remove the & to return by value, instead of by reference. Returning by reference there makes no sense because task
will be destroyed when the function returns.
Modern compilers can optimize return value to avoid copying overhead. Often returning by value doesn't hurt performance at all.
But if you need to return by reference, use shared_ptr instead.
shared_ptr<Task> TaskSample::Create(void)
{
shared_ptr<Task> ptr(new Task(...));
return ptr;
}
The best would be, to pass the object by reference as follows
void TaskSample::Create(Task& data)
{
....
}
Both of the following code snippets produce this error in MS C++:
warning C4172: returning address of local variable or temporary
Task* Create(void)
{
Task task;
return &task;
}
Task& Create2(void)
{
Task task;
return task;
}
MSDN documentation describes the warning quite succintly:
Local variables and temporary objects are destroyed when a function returns, so the address returned is not valid.
In order to return a pointer to an object you need to call operator new
as an object allocated on the heap will not go out of scope:
Task* Create(void)
{
Task* task = new Task();
return task;
}
Don't forget to delete
that task once you are done with it:
Task* task = Create();
delete task;
Alternatively you can use a smart pointer:
void Test () {
boost::scoped_ptr<Task> spTask = Create();
spTask->Schedule();
} //<--- spTask is deleted here
I would instead rely on RVO and actually use the code that you posted and which is most likely not the code giving you a warning.
void Test() {
Task task = Create();
}
Task Create(void)
{
Task task;
task.start = 10;
return task;
}
This may generate something equivalent to this, so really, there is no copy constructor overhead.
void Test() {
Task task;
Create(&task);
}
Task* Create(Task* __compilerGeneratedParam)
{
__compilerGeneratedParam->start = 10;
return __compilerGeneratedParam;
}