关于全局变量的外部声明"C"外部声明
Extern declaration on an extern "C" global variable
在C和C++中,如果我想在其他编译单元中使用全局变量,我会定义如下变量:
int g_myVal = 0;
这将为int
分配存储。
然后在头文件中,我声明变量:
extern int g_myVal;
这通知编译器所述符号存在于某个其他编译单元中。然后由链接器来解析符号。
但是,如果我希望变量与"C"链接可用,我必须定义变量(分配存储),如:
extern "C" int g_myVal = 0;
那么,如何区分分配存储和仅仅通知编译器所述符号存在于另一个编译单元中呢?
您的困惑源于extern
和extern "C"
做两件不同的事情。
关于extern
extern
本身就是存储类说明符:
[C++11: 7.1.1/6]:
extern
说明符只能应用于变量和函数的名称。extern
说明符不能用于类成员或函数参数的声明中。有关用extern
说明符声明的名称的链接,请参见3.5[注意:extern
关键字也可以用于显式实例化和链接规范,但在此类上下文中,它不是存储类说明符。--结束注释]
关于extern "C"
正如后面的注释所暗示的,还有另一个上下文可以在其中使用extern
关键字,即作为链接说明符:
C++和非C++代码片段之间的
[C++11: 7.5/2]:
链接(3.5)可以使用链接规范来实现:链接规范:
nbspextern
字符串文字{
声明seqopt}
nbsp;extern
字符串文字声明
C++喜欢重复使用关键字。
声明与定义
现在,默认情况下,用链接说明符标记的变量是声明,而不是定义。因此,从这个意义上讲,就好像您也使用了extern
:的其他含义
[C++11: 7.5/7]:
直接包含在链接规范中的声明被视为包含extern
说明符(7.1.1),用于确定声明名称的链接以及它是否是定义。此类声明不得指定存储类别[示例:extern "C" double f(); static double f(); // error extern "C" int i; // declaration extern "C" { int i; // definition } extern "C" static void g(); // error
—结束示例]
正如您在上面的示例中看到的,当您使用链接说明符时,仍然可以声明或定义。
这是另一个例子:
// Everything in this block has C linkage
extern "C" {
// Declaration of g_myVal
extern int g_myVal;
// Definition of g_myVal2
int g_myVal2;
}
int main()
{
g_myVal2 = 5; // ok
g_myVal = 6; // not okay - linker error, symbol not found
}
现场演示
添加初始化程序时
话虽如此,g_myVal
作为声明的处理被您使用的初始化器所否决,这迫使该声明成为一个定义:
[C++11: 7/8]:
在一般声明形式中发现的语法组件之外的语法组件被添加到函数声明中,以形成函数定义但是,对象声明也是一个定义,除非它包含extern
说明符并且没有初始值设定项(3.1)。定义会保留适当的存储量并完成任何适当的初始化(8.5)。
我希望这能澄清代码中extern
的不同含义。
在这种情况下,放置初始值设定项= 0
将声明更改为定义,这就是为什么在此处分配存储的原因。(即使只有普通的extern
也会发生同样的情况。)
- C++ 没有在命名空间外部声明的类主体的类
- C++:在循环内部或外部声明一个向量
- 我可以清除外部声明为进一步使用的数组吗?
- C++中"T 的未知边界数组"的外部声明
- 如果在函数中使用外部声明怎么办
- 如何在类外部声明专业模板方法
- 关于全局变量的外部声明"C"外部声明
- 外部声明变量的定义适用于一个函数,但不适用于另一个函数
- 用于在方法或函数外部声明的变量的内存
- 动态调度在类外部声明的方法
- C++外部声明隔离
- 有没有办法从类外部声明一个受保护C++变量?
- 带有 throw() 的外部声明
- 在函数外部声明对象,将其作为引用传递,然后在函数内部创建它
- 使用 "auto" 的声明是否与使用具体类型说明符的外部声明匹配?
- 访问在类外部声明的作用域枚举
- 这些外部声明在C++有什么区别
- 全局变量外部声明后的线程专用指令
- c++变量外部声明
- c++:在类内部从外部声明枚举器,以便可以在私有成员中使用