未定义的对静态局部变量的引用

Tim*_*imo 9 c++ static g++ c++11

这是我能想出的最简单的例子来重现问题.

template<class T>
struct X
{
    static void foo()
    {
        static int z = 0;
        []{ z = 1; }();
    }
};

int main()
{
    X<int>::foo();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试过使用MinGW 4.6和4.7,以及Ubuntu中的g ++ 4.6,所有这些都给我链接错误"undefined reference to z".所以现在这让我想知道这是否合法.VC10没问题.

如果X是普通类而不是模板,它可以工作.另外,我认为它与lambdas无关,因为即使我用本地类替换lambda也会出错.

use*_*016 10

g ++接受以下内容,但VC++不支持:

[&z]{ z = 1; }();
Run Code Online (Sandbox Code Playgroud)

z是被捕获的所以g ++不会抱怨未定义的引用.然而:

5.1.2/10:

使用通常的非限定名称查找规则(3.4.1)查找捕获列表中的标识符; 每个这样的查找应该找到一个变量,其自动存储持续时间在本地lambda表达式的到达范围内声明.

z自动存储.z因此无法捕获.因此,g ++行为不正确,VC++是正确的.

在您的代码中,VC++接受而g ++不接受:

[]{ z = 1; }();
Run Code Online (Sandbox Code Playgroud)

zVC++作为静态存储访问,这在lambda体中是允许的.g ++显然没有将名称解析z为上面声明的静态变量,因此抛出未定义的引用,而不应该.

tl; dr 这可能是g ++中的一个错误

编辑: 这确实是一个错误,并在4.7中修复.