Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undefined reference to a static local variable

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.

like image 784
Timo Avatar asked Dec 29 '11 10:12

Timo


1 Answers

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.

like image 106
user703016 Avatar answered Oct 19 '22 11:10

user703016