繁体   English   中英

使用未命名命名空间中的外部链接初始化变量

[英]Initialization of variable with external linkage inside unnamed namespace

我想为“ x”提供一个定义。 我尝试使用“ extern int x = 42”。 但是,g ++抱怨'x'同时具有extern和初始化程序。 我试图找到不允许这样做的c ++ 11规范的相关部分,但找不到任何此类子句。 规格确实不允许这样做吗? 如果是这样,请引用相关部分。

namespace {
    int f() { 
        extern int x;
        return x;
    }
}

通过提供初始化程序,您可以将声明转换为具有外部链接的定义

§3.1/ 2 [basic.def]

声明是一个定义,除非它在未指定函数主体(8.4)的情况下声明函数, 它包含extern说明符 (7.1.1)或链接规范 (7.5), 并且既不包含初始化程序也不包含function-body...

但是带有外部链接的变量不能在函数中定义,只能在名称空间范围内定义,这就是gcc拒绝代码的原因。 因此在命名空间范围内提供定义。

namespace {
    extern int x = 0;
    int f() { 
        // no need for extern declaration here, name lookup will find x
        return x;
    }
}

可以,但是将外部链接赋予未命名名称空间中定义的名称当然很奇怪,即使不是没有用的。


请注意,gcc仍会对上面的代码发出警告

警告:“ x”已初始化并声明为“ extern”

但是,此gcc错误报告中有关于警告的信息:

这是一种编码风格的警告-该代码有效,但对于C语言来说却极为不合常规,因为通常期望“ extern”表示该声明未提供该对象的定义。

3.5 / 6

在块作用域中声明的函数名称与在块作用域extern声明中声明的变量名称具有链接。 如果存在具有相同名称和类型的链接的实体的可见声明,而忽略在最内层封闭的命名空间范围之外声明的实体,则块范围声明将声明该相同的实体并接收先前声明的链接。 如果有多个这样的匹配实体,则程序格式错误。 否则,如果未找到匹配实体,则块作用域实体将接收外部链接。

8.5 / 5

具有外部或内部链接且具有初始化程序的块范围变量的声明格式错误。

正如@Praetorian指出的那样,您可以将变量定义移到函数定义之外。 或者,如果您实际上不需要在该功能之外的任何地方使用名称xstatic extern更改为static ,并且x将没有链接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM