Reputation: 14827
In the code sample below, I would expect the output to be as follows, since x
is a static constexpr
variable.
5
5
5
5
However, g++ warns me that x
is uninitialized inside the lambda function when I compile with -Wall
, and the last three lines of the output vary, presumably because the value of uninitialized memory on the stack is being printed. Here is one possible output produced by the program when it is compiled with the options -Wall -std=c++0x
. Why is the output not what I expect it to be?
5
32718
32718
32718
If it helps, the expected output is produced when constexpr
is deleted in the declaration constexpr T x
.
#include <algorithm>
#include <iostream>
struct _foo
{
template <class T>
struct traits
{
static constexpr T val = 5;
};
template <class T>
constexpr T getval() const { return traits<T>::val; }
} foo;
struct _test
{
template <class T>
void bar(const T& t)
{
int arr[] = { 1, 2, 3 };
constexpr T x = foo.getval<T>();
std::cout << x << std::endl;
std::for_each(arr, arr + 3, [&](int i) {
std::cout << x << std::endl;
});
}
} test;
int main()
{
test.bar(5u);
return 0;
}
Upvotes: 2
Views: 380
Reputation: 14827
This was indeed a compiler bug. I reported it here, and it was confirmed a while ago. It doesn't crash on older versions of g++, because the constexpr keyword is just parsed and ignored.
Upvotes: 2
Reputation: 75130
You have to capture x
in the lambda's capture list:
std::for_each(arr, arr + 3, [&](int i) { // notice the & (capture the outside env
// by reference
std::cout << x << std::endl;
});
Upvotes: 0