首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对静态局部变量的引用未定义

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

Stack Overflow用户
提问于 2011-12-29 18:15:26
回答 2查看 695关注 0票数 9

这是我能想到的重现这个问题的最简单的例子。

代码语言:javascript
复制
template<class T>
struct X
{
    static void foo()
    {
        static int z = 0;
        []{ z = 1; }();
    }
};

int main()
{
    X<int>::foo();
    return 0;
}

我已经在Ubuntu4.6和4.7以及MinGW的g++ 4.6上尝试过了,它们都给了我一个链接错误"undefined reference to `z'“。所以现在我开始怀疑这是不是合法的。VC10对此没有问题。

如果X是普通类而不是模板,那么它就会起作用。此外,我不认为它与lambda相关,因为即使我用本地类替换lambda,我也会得到错误。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-12-29 18:23:03

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

代码语言:javascript
复制
[&z]{ z = 1; }();

这里捕获了z,因此g++不会抱怨未定义的引用。但是:

5.1.2/10:

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

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

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

代码语言:javascript
复制
[]{ z = 1; }();

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

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

编辑: It is indeed a bug,已在4.7中修复。

票数 10
EN

Stack Overflow用户

发布于 2011-12-29 19:08:30

我不明白为什么它只适用于普通类,而不适用于模板。但是,如果通过引用捕获本地变量z,则可以使示例正常工作:

代码语言:javascript
复制
static void foo()
{
    static int z = 0;
    [&z]{ z = 1; }(); // Note: [&z]
}

维基百科有更多信息here

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8666492

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档