This is the simplest example I could come up with that reproduces the problem.
template<class T>
struct X
{
static void foo()
{
static int z = 0;
[]{ z = 1; }();
}
};
int main()
{
X<int>::foo();
return 0;
}
I've tried it with MinGW 4.6 and 4.7, also g++ 4.6 in Ubuntu and all of them give me the link error "undefined reference to `z'". So now that makes me wonder if this is even legal. VC10 has no problem with it.
It works if X is normal class instead of a template. Also, I don't think it's related to lambdas cause I get the error even if I replace the lambda with a local class.
g++ accepts the following, but VC++ does not:
[&z]{ z = 1; }();
Here z
is being captured so g++ does not complain about an undefined reference. However:
5.1.2/10:
The identifiers in a capture-list are looked up using the usual rules for unqualified name lookup (3.4.1); each such lookup shall find a variable with automatic storage duration declared in the reaching scope of the local lambda expression.
z
is not automatic storage. z
can therefore not be captured. g++ behavior is therefore incorrect, and VC++ is correct.
In your code, that VC++ accepts and g++ does not:
[]{ z = 1; }();
z
is accessed by VC++ as static storage, which is allowed in a lambda body. g++ apparently does not resolve the name z
to the static variable declared above and therefore throws undefined reference, while it shouldn't.
tl;dr It's probably a bug in g++
Edit: It is indeed a bug and is fixed in 4.7.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With