c++ extern
参考链接:https://learn.microsoft.com/zh-cn/cpp/cpp/extern-cpp?view=msvc-170
重要信息摘录如下:
关键字 extern 可以应用于全局变量、函数或模板声明。 它指定符号具有 external 链接。 有关链接的背景信息以及为何不鼓励使用全局变量,请参阅翻译单元和链接。
关键字 extern 具有四种含义,具体取决于上下文:
在非 const 全局变量声明中,extern 指定变量或函数在另一个转换单元中定义。 必须在除定义变量的文件之外的所有文件中应用 extern。
在 const 变量声明中,它指定变量具有 external 链接。 extern 必须应用于所有文件中的所有声明。 (默认情况下,全局 const 变量具有内部链接。)
extern "C" 指定函数在别处定义并使用 C 语言调用约定。 extern "C" 修饰符也可以应用于块中的多个函数声明。
在模板声明中,extern 指定模板已在其他位置实例化。 extern 告知编译器它可以重复使用另一个实例化,而不是在当前位置创建新实例。 有关使用 extern 的详细信息,请参阅显式实例化。
1 extern 非 const 变量
就是一处定义变量(不需要声明extern),其他地方使用extern 声明一下,即可使用。
用法 | 结果 |
---|---|
定义的地方extern,用的地方不extern | 报错,a重定义 |
定义的地方extern,用的地方extern | 用的地方成功拿到定义的地方的值了,但是有一个warning |
定义的地方不extern,用的地方不extern | 报错,a重定义 |
定义的地方不extern,用的地方extern | 用的地方成功拿到定义的地方的值了 |
注意:
只能是定义的地方不用extern,其他用的地方extern,不能定义的地方extern,而其他用的地方直接用。
如果是在定义的地方extern,而在用的地方不extern,也不声明就会报如下错误:
D:\code\c\test_extern2>make
g++ 1.cpp 2.cpp -o main.exe
1.cpp:8:15: warning: 'a' initialized and declared 'extern'
extern string a="hello a";
^
2.cpp: In function 'void f()':
2.cpp:7:18: error: 'a' was not declared in this scope
cout<<"f(): "<<a<<endl;
^
make: *** [Makefile:2: main.exe] Error 1
如果是在定义的地方extern,而用的地方只声明不extern,那么会报下面的错误:
D:\code\c\test_extern2>make
g++ 1.cpp 2.cpp -o main.exe
1.cpp:8:15: warning: 'a' initialized and declared 'extern'
extern string a="hello a";
^
C:\Users\lishg1\AppData\Local\Temp\ccSZBmwZ.o:2.cpp:(.bss+0x0): multiple definition of `a[abi:cxx11]'
C:\Users\lishg1\AppData\Local\Temp\ccIMWM2W.o:1.cpp:(.bss+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
make: *** [Makefile:2: main.exe] Error 1
如果是在定义的地方extern,用的地方也extern,就会只有一个warning。
D:\code\c\test_extern2>make
g++ 1.cpp 2.cpp -o main.exe
1.cpp:8:15: warning: 'a' initialized and declared 'extern'
extern string a="hello a";
总结就是:非const变量,在定义的时候不需要extern,只在用的地方extern声明就好。
测试样例如下:
1.cpp
#include <iostream>
#include <string>
#include "2.h"
using namespace std;
string a="hello a";
int main (int argc, char *argv[]) {
cout<<a<<endl;
f();
return 0;
}
2.h
#ifndef _2_H
#define _2_H
#include <iostream>
#include <string>
using namespace std;
void f();
#endif //!_2_H
2.cpp
#include "2.h"
extern string a;
void f()
{
cout<<"f(): "<<a<<endl;
}
Makefile
main.exe: 1.cpp 2.cpp
g++ 1.cpp 2.cpp -o main.exe
2 extern const 变量
extern const 变量,其他用的地方也必须要extern。
用法 | 结果 |
---|---|
定义的地方extern,用的地方不extern | 两个变量各是各的,不相同 |
定义的地方extern,用的地方extern | 用的地方成功拿到定义的地方的值了 |
定义的地方不extern,用的地方不extern | 两个变量各是各的,不相同 |
定义的地方不extern,用的地方extern | 报错,a未定义 |
总结:extern const变量,定义的地方和用的地方都要extern
测试样例:
1.cpp
#include <iostream>
#include <string>
#include "2.h"
using namespace std;
//extern const string a="hello a";
const string a="hello a";
int main (int argc, char *argv[]) {
cout<<a<<endl;
f();
return 0;
}
2.h
#ifndef _2_H
#define _2_H
#include <iostream>
#include <string>
using namespace std;
void f();
#endif //!_2_H
2.cpp
#include "2.h"
//const string a;
extern const string a;
void f()
{
cout<<"f(): "<<a<<endl;
}
Makefile
main.exe: 1.cpp 2.cpp
g++ 1.cpp 2.cpp -o main.exe