...
Code Block |
---|
|
#include <initializer_list>
#include <iostream>
#include <vector>
class C {
std::vector<int> L;
public:
C() : L{1, 2, 3} {}
int first() const { return *L.begin(); }
};
void f() {
C c;
std::cout << c.first();
} |
Noncompliant Code Example
In this noncompliant code example, a lamdba object is stored in a function object, which is later called (executing the lambda) to obtain a constant reference to a value. The lambda object returns an int
value, which is then stored in a temporary int
object that becomes bound to the const int &
return type specified by the function object. However, the temporary object's lifetime is not extended past the return from the function object's invocation, which results in undefined behavior when the resulting value is accessed.
Page properties |
---|
|
There is reflector discussion that this may wind up being a DR, however, there is implementation divergence on the behavior currently with Clang 3.7 reporting "42" and GCC reporting a random value. The discussion starts with c++std-lib-37670 |
Code Block |
---|
|
#include <functional>
void f() {
auto l = [](const int &j) { return j; };
std::function<const int&(const int &)> fn(l);
int i = 42;
int j = fn(i);
} |
Compliant Solution
In this compliant solution, the std::function
object returns an int
instead of a const int &
, ensuring that the value is copied instead of bound to a temporary reference. An alternative solution would be to call the lambda directly, instead of through the std::function
object.
Code Block |
---|
|
#include <functional>
void f() {
auto l = [](const int &j) { return j; };
std::function<int(const int &)> fn(l);
int i = 42;
int j = fn(i);
} |
Risk Assessment
Referencing an object outside of its lifetime can result in an attacker being able to run arbitrary code.
...