Undefined behavior of std :: future as a return type?
In my case, I am using std :: future as the return type, but I get undefined behavior. Code below:
#include <future>
#include <iostream>
#include <pthread.h>
std::future<bool> update() {
int c = 1;
//std::cout << "?" << c << std::endl; // debug line
auto lambda = [&] () -> bool {
int b = 0;
for(int i = 0; i < 10000000; ++i) {
b += 1;
}
std::cout << "?" << c << std::endl;
return c == 1;
};
return std::async(std::launch::async, lambda);
}
int main(int argc, char *argv[])
{
auto f2 = update();
std::cout << f2.get() << std::endl;
return 0;
}
I compiled this piece of code g++-4.7.2 -std=c++11 test_future.cc -lpthread
and got the following output:
?0
0
But when I split debug line
above, the result is 1
(as expected). Also, if I use std::future
as a parameter with a function update
instead of a return value, I can also get the correct output result.
I want to know what the problem is. G ++ error or usage error? Thank.
source to share
The problem is that you are committing the variable c
by reference, combined with the fact that you run the lambda asynchronously. The last part means that the function update
may have returned before the lambda actually executed, and now it refers to a variable that no longer exists.
The reason this works if you have a debug line is due only to undefined behavior.
So the problem has nothing to do with what you are returning std::future
.
The obvious solution is, of course, to capture c
by value instead, and if this is not possible in your actual code, you may need to rethink your design.
source to share
Sounds like undefined behavior to me. You write c
by reference, but it will fall out of scope by the time it is executed lambda
.
Hence, c == 1
this is undefined behavior because it is c
out of scope. If you are committing to a value, you should be fine.
auto lambda = [c] () -> bool {
int b = 0;
for(int i = 0; i < 10000000; ++i) {
b += 1;
}
std::cout << "?" << c << std::endl;
return c == 1;
};
source to share