C++中的静态全局变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14349877/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Static global variables in C++
提问by Christian Daley
I would like to make an array of integers via the malloc method. I want this array to be global and be used anywhere in my program. I put code in a header file that looked like this:
我想通过 malloc 方法制作一个整数数组。我希望这个数组是全局的,并且可以在我的程序中的任何地方使用。我把代码放在一个看起来像这样的头文件中:
static int *pieces;
Then I have a function that fills it with numbers that I want in there. The function is in a namespace and the namespace is implemented in its own .cpp file. However, I import the header file into main.c and call the function from the namespace that creates the array like:
然后我有一个函数,用我想要的数字填充它。该函数位于命名空间中,并且该命名空间在其自己的 .cpp 文件中实现。但是,我将头文件导入 main.c 并从创建数组的命名空间调用函数,如:
pieces = malloc(sizeof(int) * 128);
But when I try to access numbers in the array in main (after calling the function that creates my array), it crashes and says that pieces wasn't initialized. But in the function I have I can create it and manipulate the numbers in it just fine. I was under the impression that by making pieces a static variable, whenever some function anywhere changes (or sets it) then that will affect the usage of the variable anywhere. Basically what I'm trying to say is why does pieces appear unset in main, even though I set it in a function that I called?
但是当我尝试在 main 中访问数组中的数字时(在调用创建我的数组的函数之后),它崩溃并说这些部分没有被初始化。但是在我拥有的函数中,我可以创建它并很好地操纵其中的数字。我的印象是,通过使部分成为静态变量,每当任何地方的某个函数更改(或设置它)时,都会影响该变量在任何地方的使用。基本上我想说的是为什么即使我将它设置在我调用的函数中,它也会在 main 中出现未设置?
回答by Karthik T
Static
is a keyword with many meanings, and in this particular case, it means not global(paraphrasing)
Static
是一个具有多种含义的关键字,在这种特殊情况下,它意味着不是全局的(释义)
It means that each .cpp
file has its own copyof the variable. Thus, when you initialize in main.cpp
, it is initialized ONLY in main.cpp
. The other files have it still uninitialized.
这意味着每个.cpp
文件都有自己的变量副本。因此,当您在 中初始化时main.cpp
,它仅在 中初始化main.cpp
。其他文件仍未初始化。
First thing to fix this would be to remove the keyword static
. That would cause the "Multiple definitions issue". To fix this you should define the variable in a .cpp
file and just extern declare it in a header file.
解决这个问题的第一件事是删除关键字static
。这将导致“多重定义问题”。要解决此问题,您应该在.cpp
文件中定义变量,然后在头文件中对其进行 extern 声明。
Edit: You are just allocating memory to it, doesnt count as initialization. You need to initialize the memory to 0 after allocation.
编辑:您只是为其分配内存,不算作初始化。分配后需要将内存初始化为0。
You can use new int[128]()
instead of your more verbose malloc
syntax, and this would perform initializationas well? Or you could take the easy road (thats what its there for) and use std::vector
您可以使用new int[128]()
更详细的malloc
语法代替,这也将执行初始化?或者你可以走简单的路(这就是它的用途)并使用std::vector
回答by paddy
The key is this:
关键是这样的:
static int *pieces;
You said you put that in your header. This is not the way to export a symbol. Any file that includes the header will get its own static version of an uninitialised pointer called pieces
.
你说你把它放在你的标题中。这不是导出符号的方式。任何包含标头的文件都将获得自己的静态版本的未初始化指针,称为pieces
.
Instead, you put this in your header:
相反,你把它放在你的标题中:
extern int *pieces;
extern int init_pieces();
And in the source file, you do this:
在源文件中,您执行以下操作:
static const size_t num_pieces = 128;
int *pieces = 0;
int init_pieces()
{
pieces = malloc( num_pieces * sizeof(int) );
return pieces != NULL;
}
Now when you include your header, your source file will know to get pieces
from somewhere else, and will wait for the linker to work out where. I also suggested an 'init' function for the array. I did not put a 'release' function in, however.
现在,当您包含标头时,您的源文件将知道pieces
从其他地方获取,并等待链接器确定在哪里。我还为数组建议了一个 'init' 函数。但是,我没有放入“发布”功能。
Note this is all C, not C++. If you're using C++ you should really use new
or better still, use a vector
.
请注意,这都是 C,而不是 C++。如果您使用的是 C++,您应该真正使用new
或更好,使用vector
.
Also, when using statics in C++, be mindful of this: C++ static initialization order
另外,在 C++ 中使用 statics 时,请注意这一点:C++ 静态初始化顺序
回答by topin89
In C++17 standard, you can use inline
specifier instead of static. For variables this means every object unit will have a copy of the variable, but linker will choose only one of them.
Or, as stated on cppreference:
在 C++17 标准中,您可以使用inline
说明符代替静态。对于变量,这意味着每个对象单元都会有一个变量的副本,但链接器只会选择其中一个。或者,如cppreference 所述:
An inline function or inline variable (since C++17) has the following properties:
1) There may be more than one definition of an inline function or variable (since C++17) in the program as long as each definition appears in a different translation unit and (for non-static inline functions and variables (since C++17)) all definitions are identical. For example, an inline function or an inline variable (since C++17) may be defined in a header file that is #include'd in multiple source files.
2) The definition of an inline function or variable (since C++17) must be present in the translation unit where it is accessed (not necessarily before the point of access).
3) An inline function or variable (since C++17) with external linkage (e.g. not declared static) has the following additional properties:
1) It must be declared inline in every translation unit. 2) It has the same address in every translation unit.
内联函数或内联变量 (C++17 起)具有以下属性:
1) 只要每个定义出现在不同的翻译单元中并且(对于非静态内联函数和变量(自 C+ +17)) 所有定义都是相同的。例如,一个内联函数或一个内联变量(C++17 起)可以在多个源文件中#include 的头文件中定义。
2) 内联函数或变量(C++17 起)的定义必须存在于访问它的翻译单元中(不一定在访问点之前)。
3) 具有外部链接(例如未声明为静态)的内联函数或变量(C++17 起)具有以下附加属性:
1) It must be declared inline in every translation unit. 2) It has the same address in every translation unit.
Supported in (source):
支持(来源):
- MSVC since version 19.12 (VS 2017 15.5)
- GCC 7
- Clang 3.9
- ICC 18.0
- MSVC 自版本 19.12 (VS 2017 15.5)
- 海湾合作委员会 7
- 叮当 3.9
- 国际商会 18.0
In this case, it means you can replace
在这种情况下,这意味着您可以更换
static int *pieces;
with
和
inline int *pieces;
回答by Joel Giedt
For high performance code on various architectures, you may want a malloc-y allocation rather than generic new. That is because you would wrap it with something like mymalloc() and then use architecture dependent functions, such as ones that implement the proper alignment to avoid cache misses and do other nifty things provided by the hardware manufacturer, such as IBM (Bluegene) or Intel (MIC). All of these optimized allocation routines have the malloc type framework.
对于各种体系结构上的高性能代码,您可能需要 malloc-y 分配而不是通用的 new。那是因为你会用 mymalloc() 之类的东西包装它,然后使用依赖于体系结构的函数,例如实现正确对齐以避免缓存未命中的函数,并执行硬件制造商提供的其他漂亮的事情,例如 IBM (Bluegene) 或英特尔 (MIC)。所有这些优化的分配例程都具有 malloc 类型框架。