在什么情况下可以在定义中使用外部变量?

Cpp*_*ner 2 c++ variables memory-management extern

我很抱歉.我不知道我的不完整的代码附件会造成如此混乱.我很高兴看到这么多真诚的帮助.

这段代码将编译:

int myadd(int, int);
static int main_stat = 5;

int main()
{
    int i, j;
    main_stat = 13;
    j = myadd(-1,7);
    i = main_stat;

    cout << j << i;     //  3  and 13
    return 0;

}
Run Code Online (Sandbox Code Playgroud)

myadd.cpp

extern int main_stat = -3;
int myadd(int x,int y)
{
    int t = main_stat;
    t = x + y;
    y = t +main_stat;
    return y;    // will return 3
}
Run Code Online (Sandbox Code Playgroud)

请参阅我定义和extern链接main_stat.为什么合法?我以为你只能链接而不能定义.

存储是否在myadd函数调用的堆栈帧中分配?我相信全局静态是在堆上分配的,对吧?


编辑

对不起,我想这次我会缩小我的问题范围:

来自C++ Primer 4ed

一个的extern声明可以包括一个初始化器(结合时变得清晰),只有当它出现在函数之外.

我清楚一个定义规则.

Q1.myadd(int,int)在调用时使用了main_stat的哪个副本?与主要相同的副本,但具有不同的值(我可以测试)?或者每个函数都有自己的静态全局副本吗?

Q2.是否在堆上为这些全局静态变量分配了内存?我知道很多事情都要实现,但是不是用于静态变量的堆?

Q3.我知道以下两个是有效的

extern int x;    // means int x is defined elsewhere
extern int x = 3;  // declared and defined 
Run Code Online (Sandbox Code Playgroud)

如果我们可以在myadd的命名空间中声明一个静态全局变量,为什么我们需要第二个?如何像aschepler所说的那样让事情变得清晰

Jam*_*nze 9

具有初始值设定项的所有变量声明也是定义; 这是一个压倒一切的规则.无论如何extern.甚至有些情况下您需要extern定义:您只能使用具有外部链接的变量来实例化模板.并且 const变量默认具有内部链接,因此您需要以下内容:

extern int const i = 42;
Run Code Online (Sandbox Code Playgroud)

如果你想用它来实例化一个template<int const*>.