Is there any difference between a variable declared as static
outside any function between C and C++. I read that static
means file scope and the variables will not be accessible outside the file. I also read that in C, global variables are static
. So does that mean that global variables in C can not be accessed in another file?
在C和c++之间的函数之外声明为静态的变量之间有什么区别吗?我读到静态意味着文件范围和变量在文件之外是不可访问的。我还在C中读到,全局变量是静态的。那么这是否意味着C中的全局变量不能在另一个文件中访问?
5 个解决方案
#1
16
No, there's no difference between C and C++ in this respect.
不,在这方面,C和c++没有区别。
Read this SO answer about what static
means in a C program. In C++ there are a couple of other meanings related to the use of static
for class variables (instead of instance variables).
请阅读本文,回答关于C程序中静态的含义。在c++中,与类变量使用静态(而不是实例变量)相关的还有一些其他含义。
Regarding global vars being static
- only from the point of view of memory allocation (they are allocated on the data segment, as all globals are). From the point of view of visibility:
关于全局vars是静态的—仅从内存分配的角度来看(它们与所有全局变量一样被分配到数据段上)。从可见性的角度来看:
static int var; // can't be seen from outside files
int var; // can be seen from outside files (no 'static')
#2
7
There are two concepts here "static linkage (or scope)" and static allocation".
这里有两个概念“静态链接(或范围)”和静态分配。
Outside a function the keyword refers to linkage, inside it refers to allocation. All variables outside a function have static allocation implicitly. An unfortunate design perhaps, but there it is.
函数外的关键字是指链接,内的是指分配。函数之外的所有变量都具有隐式的静态分配。这也许是一个不幸的设计,但它就在那里。
#3
5
C and C++ are the same.
C和c++是一样的。
static does two different things.
静态做两件事。
For variables declared outside a function scope, it changes the visibility (linkage) of the variable. The variable will be a global variable since it is outside a function scope. If it isn't static, it will have universal linkage (visibility) so any code linked together with this can access it (they may have to declare it extern). If the variable is outside a function scope and is static, it still a global variable in that it always exists and keeps its value, but no code outside the same compilation unit (that .c file and any .h's included) can access it.
对于在函数作用域中声明的变量,它会改变变量的可见性(链接)。该变量将是一个全局变量,因为它不在函数范围之内。如果它不是静态的,那么它将具有通用链接(可见性),因此任何链接在一起的代码都可以访问它(它们可能必须声明它为extern)。如果变量在函数范围之外并且是静态的,那么它仍然是一个全局变量,因为它始终存在并保持其值,但是在同一编译单元(包括.c文件和任何.h)之外的任何代码都不能访问它。
For variables declared inside a function scope, static changes the location where the variable is stored. If it is not static, it will be an automatic variable, that means it disappears as the function exits and comes back into existence (on the stack) when the function is entered again. This it loses its value when you exit the function. And also any references to it (pointers to it) are invalid after the function exits. If a variable declared inside a function scope is static, then it makes it not an automatic variable but a globally allocated one. So the variable will exist after the function exits and thus will keep its value across invocations of the function and also any references (pointers) to it are valid even after the function exits. Note that in both cases the scope of the variable is only within that function so it's not possible to access it directly (but only via saved reference) from outside the function scope.
对于在函数作用域中声明的变量,静态会更改存储变量的位置。如果它不是静态的,它将是一个自动变量,这意味着当函数退出时它将消失,当函数再次输入时它将返回存在(在堆栈上)。当你退出函数时,它会失去它的值。而且,在函数退出后,对它的任何引用(指向它的指针)都是无效的。如果函数作用域中声明的变量是静态的,那么它就不是自动变量,而是全局分配的变量。因此,该变量将在函数退出后存在,因此在函数调用时保持其值,并且即使在函数退出后,对它的任何引用(指针)也是有效的。注意,在这两种情况下,变量的范围都只在函数范围内,所以不可能从函数范围之外直接访问它(但只能通过保存的引用)。
One last thing static does is change when the initializer (i.e. int foo = 5) for the variable is run. For all the cases where the allocation is global (every case except the automatic one), the initializer is run only once, at the beginning of the execution of your program. It is run before main() is run even, so you can get some not quite expected result if your initializer isn't just a constant number but runs some code. For the automatic case, the initializer is run every time the function is entered, and in this case it is always after main() has been entered.
静态做的最后一件事是当变量的初始化器(即int foo = 5)运行时更改。对于所有分配是全局的情况(除了自动的情况),初始化器只在程序执行的开始运行一次。它是在main()运行之前运行的,所以如果初始化器不是一个常量,而是运行一些代码,那么就会得到一些不太理想的结果。对于自动情况,每次输入函数时都会运行初始化器,在这种情况下,它总是在main()输入之后。
#4
1
I want to add to Southern Hospitality's answer Static variables in C and C++
我想在C和c++中添加Southern Hospitality的回答静态变量
the following remarks:
以下评论:
The use of static
to indicate "local to translation unit" is deprecated in C++ ( href="http://rads.*.com/amzn/click/0201700735" The C++ Programming Language: Special Edition, Appendix B.2.3, Deprecated Features).
在c++中,不赞成使用静态来表示“本地到翻译单元”(href="http://rads.*.com/amzn/click/0201700735" c++编程语言:特殊版本,附录B.2.3,不赞成的特性)。
You should use unnamed namespaces instead:
您应该使用未命名的名称空间:
static int reply = 42; // deprecated
namespace {
int reply1 = 42; // The C++ way
}
As already said by Southern Hospitality, the order of initialization of global objects is undefined. In that situation, you should consider using the href="http://en.wikipedia.org/wiki/Singleton_pattern#C.2B.2B", Singleton pattern.
正如Southern Hospitality所说,全局对象初始化的顺序是不确定的。在这种情况下,您应该考虑使用href=“http://en.wikipedia.org/wiki/Singleton_pattern#C.2B.2B”,单例模式。
UPDATE: GMan commented my answer:
更新:GMan评论了我的回答:
"The order is defined per-translation unit, ...": This really slipped my mind, so I looked it up in The C++ Programming Language.
“顺序是按翻译单位定义的,……”我真的忘记了,所以我用c++编程语言查了一下。
In Section 9.4.1, Initialization of Non-local Variables, Prof. Stroustrup suggests that "a function returning a reference is a good alternative to a global variable":
在第9.4.1节,非局部变量的初始化,Stroustrup教授建议,“返回引用的函数是全局变量的一个好选择”:
int& use_count()
{
static int uc = 0;
return uc;
}
"A call to use_count()
now acts as a global variable that is initialized at its first use. For example:"
对use_count()的调用现在作为一个全局变量,在第一次使用时进行初始化。例如:“
void f()
{
std::cout << ++use_count() << '\n';
}
In my understanding, this is very similar to the Singleton pattern.
在我的理解中,这与单例模式非常相似。
GMan commented further: "We need to limit our ability to create these objects to one, and provide global access to it." Does the limiting to one really relate to anything in the problem? We may need one globally, but who's to say we don't want it in other places?"
GMan进一步评论说:“我们需要限制我们创建这些对象的能力,并提供对它们的全局访问。”对一个人的限制真的与问题中的任何东西有关吗?我们可能在全球都需要一个,但谁又能说我们不希望它出现在其他地方呢?
Some quotes from Singleton(127) (Gamma et al, Design Patterns):
单例(127)(Gamma et al, Design Patterns):
"The Singleton pattern is an improvement over global variables. It avoids polluting the name space with global variables that store sole instances."
单例模式是对全局变量的改进。它避免使用存储唯一实例的全局变量污染名称空间。
"The pattern makes it easy to change your mind and allow more than one instance of the Singleton class."
“该模式使您很容易改变想法,并允许单例类的多个实例。”
Singletons are initialized in the order they are first used.
单例对象是按照第一次使用的顺序初始化的。
In Herb Sutter, Andrei Alexandrescu, C++ Coding Standards, Item 10 says:
在Herb Sutter、Andrei亚历山大(c++编码标准)中,第10条写道:
"Avoid shared data, especially global data."
“避免共享数据,尤其是全局数据。”
Therefore I use often Singletons to avoid global data. But of course, as everything is overusable, this could be a overuse of the Singleton pattern. (Johshua Kerievsky calls this "Singletonitis" in his book "Refactoring to Patterns".)
因此,我经常使用单例来避免全局数据。但是,当然,由于一切都是可重用的,这可能是对单例模式的过度使用。(约翰舒亚·克里夫斯基(joh舒舒亚·克里夫斯基)在他的《模式重构》(重构to Patterns)一书中把这种现象称为“单发症”。)
UPDATE 2:
更新2:
(Sorry, but I cannot write comments, therefore this Update.)
(抱歉,我不能写评论,所以这次更新。)
Jalf wrote in his comment: "The gang of four were smoking something illegal when they wrote about the singleton pattern."
贾尔夫在他的评论中写道:“*在写单例模式的时候吸烟是违法的。”
Obviously, other C++ developers smoked interesting substances, too. For example, Herb Sutter (he served for over a decade as secretary and chair of the ISO C++ standards committee during the development of the second C++ standard, C++0x, and as lead architect of C++/CLI at Microsoft. Herb is currently the designer of the Prism memory model for Microsoft platforms and the Concur extensions to Visual C++ for parallel programming), wrote in C++ Coding Standards, Item 21:
显然,其他c++开发人员也使用了一些有趣的东西。例如,Herb Sutter(他在开发第二个c++标准c++ 0x期间担任ISO c++标准委员会的秘书和主席超过十年,并在微软担任c++ /CLI的首席架构师。Herb是目前微软平台的Prism内存模型的设计者,同时也是Visual c++的并行编程的Concur扩展,在c++的编码标准中写道,项目21:
"When you need such a (namespace level) variable that might depend upon another, consider the Singleton design pattern; used carefully, it might avoid implicit dependencies by ensuring that an object is initialized upon first access. Still, Singleton is a global variable in sheep's clothing, and is broken by mutual or cyclic dependencies."
“当您需要这样一个(名称空间级)变量时,可以考虑单例设计模式;小心使用,它可以通过确保在第一次访问时初始化对象来避免隐式依赖关系。不过,单例在绵羊的衣服上是一个全局变量,并且被相互或循环的依赖关系打破。
So, avoid global data, if you can. But if you have to use global data in separate translation units, Singleton should be an acceptable solution for enforcing a specific initialization sequence.
所以,如果可能的话,尽量避免使用全局数据。但是,如果您必须在单独的转换单元中使用全局数据,单例应该是执行特定初始化序列的可接受的解决方案。
Note that in the Java language global data does not even exist. Obviously, global data is substituted/emulated by the use of the Singleton design pattern.
注意,在Java语言中甚至不存在全局数据。显然,使用单例设计模式替代/模拟了全局数据。
(For I am working in my dayjob with a Java team, I strive for a maximal similarity of my C++ programs with Java programs. E.g, every class is situated in its own source file/translation unit.)
(因为我在Java团队工作,所以我希望我的c++程序与Java程序之间的相似性最大。E。g,每个类都位于它自己的源文件/翻译单元中。
#5
0
Not really a direct answer to your question, but something closely related to watch out for if you use both C and C++.
这并不是对你的问题的直接回答,但是如果你同时使用C和c++,你需要注意一些密切相关的问题。
In C++, unlike C, global variables which are declared "const" are implicitly local to the translation unit, AS IF "static" had been used.
在c++中,与C不同的是,被声明为“const”的全局变量在翻译单元中是隐式的,就像使用“静态”一样。
Example:
例子:
// file A
extern const int glob;
// file B
const int glob = 42;
This will work if you are using a C compiler but not with a C++ compiler. In C++, the glob variable in file B cannot be used from file A and the linker will generate an "unresolved reference" error.
如果您使用的是C编译器,而不是c++编译器,那么这将是可行的。在c++中,文件B中的glob变量不能从文件A中使用,链接器将生成一个“未解决的引用”错误。
#1
16
No, there's no difference between C and C++ in this respect.
不,在这方面,C和c++没有区别。
Read this SO answer about what static
means in a C program. In C++ there are a couple of other meanings related to the use of static
for class variables (instead of instance variables).
请阅读本文,回答关于C程序中静态的含义。在c++中,与类变量使用静态(而不是实例变量)相关的还有一些其他含义。
Regarding global vars being static
- only from the point of view of memory allocation (they are allocated on the data segment, as all globals are). From the point of view of visibility:
关于全局vars是静态的—仅从内存分配的角度来看(它们与所有全局变量一样被分配到数据段上)。从可见性的角度来看:
static int var; // can't be seen from outside files
int var; // can be seen from outside files (no 'static')
#2
7
There are two concepts here "static linkage (or scope)" and static allocation".
这里有两个概念“静态链接(或范围)”和静态分配。
Outside a function the keyword refers to linkage, inside it refers to allocation. All variables outside a function have static allocation implicitly. An unfortunate design perhaps, but there it is.
函数外的关键字是指链接,内的是指分配。函数之外的所有变量都具有隐式的静态分配。这也许是一个不幸的设计,但它就在那里。
#3
5
C and C++ are the same.
C和c++是一样的。
static does two different things.
静态做两件事。
For variables declared outside a function scope, it changes the visibility (linkage) of the variable. The variable will be a global variable since it is outside a function scope. If it isn't static, it will have universal linkage (visibility) so any code linked together with this can access it (they may have to declare it extern). If the variable is outside a function scope and is static, it still a global variable in that it always exists and keeps its value, but no code outside the same compilation unit (that .c file and any .h's included) can access it.
对于在函数作用域中声明的变量,它会改变变量的可见性(链接)。该变量将是一个全局变量,因为它不在函数范围之内。如果它不是静态的,那么它将具有通用链接(可见性),因此任何链接在一起的代码都可以访问它(它们可能必须声明它为extern)。如果变量在函数范围之外并且是静态的,那么它仍然是一个全局变量,因为它始终存在并保持其值,但是在同一编译单元(包括.c文件和任何.h)之外的任何代码都不能访问它。
For variables declared inside a function scope, static changes the location where the variable is stored. If it is not static, it will be an automatic variable, that means it disappears as the function exits and comes back into existence (on the stack) when the function is entered again. This it loses its value when you exit the function. And also any references to it (pointers to it) are invalid after the function exits. If a variable declared inside a function scope is static, then it makes it not an automatic variable but a globally allocated one. So the variable will exist after the function exits and thus will keep its value across invocations of the function and also any references (pointers) to it are valid even after the function exits. Note that in both cases the scope of the variable is only within that function so it's not possible to access it directly (but only via saved reference) from outside the function scope.
对于在函数作用域中声明的变量,静态会更改存储变量的位置。如果它不是静态的,它将是一个自动变量,这意味着当函数退出时它将消失,当函数再次输入时它将返回存在(在堆栈上)。当你退出函数时,它会失去它的值。而且,在函数退出后,对它的任何引用(指向它的指针)都是无效的。如果函数作用域中声明的变量是静态的,那么它就不是自动变量,而是全局分配的变量。因此,该变量将在函数退出后存在,因此在函数调用时保持其值,并且即使在函数退出后,对它的任何引用(指针)也是有效的。注意,在这两种情况下,变量的范围都只在函数范围内,所以不可能从函数范围之外直接访问它(但只能通过保存的引用)。
One last thing static does is change when the initializer (i.e. int foo = 5) for the variable is run. For all the cases where the allocation is global (every case except the automatic one), the initializer is run only once, at the beginning of the execution of your program. It is run before main() is run even, so you can get some not quite expected result if your initializer isn't just a constant number but runs some code. For the automatic case, the initializer is run every time the function is entered, and in this case it is always after main() has been entered.
静态做的最后一件事是当变量的初始化器(即int foo = 5)运行时更改。对于所有分配是全局的情况(除了自动的情况),初始化器只在程序执行的开始运行一次。它是在main()运行之前运行的,所以如果初始化器不是一个常量,而是运行一些代码,那么就会得到一些不太理想的结果。对于自动情况,每次输入函数时都会运行初始化器,在这种情况下,它总是在main()输入之后。
#4
1
I want to add to Southern Hospitality's answer Static variables in C and C++
我想在C和c++中添加Southern Hospitality的回答静态变量
the following remarks:
以下评论:
The use of static
to indicate "local to translation unit" is deprecated in C++ ( href="http://rads.*.com/amzn/click/0201700735" The C++ Programming Language: Special Edition, Appendix B.2.3, Deprecated Features).
在c++中,不赞成使用静态来表示“本地到翻译单元”(href="http://rads.*.com/amzn/click/0201700735" c++编程语言:特殊版本,附录B.2.3,不赞成的特性)。
You should use unnamed namespaces instead:
您应该使用未命名的名称空间:
static int reply = 42; // deprecated
namespace {
int reply1 = 42; // The C++ way
}
As already said by Southern Hospitality, the order of initialization of global objects is undefined. In that situation, you should consider using the href="http://en.wikipedia.org/wiki/Singleton_pattern#C.2B.2B", Singleton pattern.
正如Southern Hospitality所说,全局对象初始化的顺序是不确定的。在这种情况下,您应该考虑使用href=“http://en.wikipedia.org/wiki/Singleton_pattern#C.2B.2B”,单例模式。
UPDATE: GMan commented my answer:
更新:GMan评论了我的回答:
"The order is defined per-translation unit, ...": This really slipped my mind, so I looked it up in The C++ Programming Language.
“顺序是按翻译单位定义的,……”我真的忘记了,所以我用c++编程语言查了一下。
In Section 9.4.1, Initialization of Non-local Variables, Prof. Stroustrup suggests that "a function returning a reference is a good alternative to a global variable":
在第9.4.1节,非局部变量的初始化,Stroustrup教授建议,“返回引用的函数是全局变量的一个好选择”:
int& use_count()
{
static int uc = 0;
return uc;
}
"A call to use_count()
now acts as a global variable that is initialized at its first use. For example:"
对use_count()的调用现在作为一个全局变量,在第一次使用时进行初始化。例如:“
void f()
{
std::cout << ++use_count() << '\n';
}
In my understanding, this is very similar to the Singleton pattern.
在我的理解中,这与单例模式非常相似。
GMan commented further: "We need to limit our ability to create these objects to one, and provide global access to it." Does the limiting to one really relate to anything in the problem? We may need one globally, but who's to say we don't want it in other places?"
GMan进一步评论说:“我们需要限制我们创建这些对象的能力,并提供对它们的全局访问。”对一个人的限制真的与问题中的任何东西有关吗?我们可能在全球都需要一个,但谁又能说我们不希望它出现在其他地方呢?
Some quotes from Singleton(127) (Gamma et al, Design Patterns):
单例(127)(Gamma et al, Design Patterns):
"The Singleton pattern is an improvement over global variables. It avoids polluting the name space with global variables that store sole instances."
单例模式是对全局变量的改进。它避免使用存储唯一实例的全局变量污染名称空间。
"The pattern makes it easy to change your mind and allow more than one instance of the Singleton class."
“该模式使您很容易改变想法,并允许单例类的多个实例。”
Singletons are initialized in the order they are first used.
单例对象是按照第一次使用的顺序初始化的。
In Herb Sutter, Andrei Alexandrescu, C++ Coding Standards, Item 10 says:
在Herb Sutter、Andrei亚历山大(c++编码标准)中,第10条写道:
"Avoid shared data, especially global data."
“避免共享数据,尤其是全局数据。”
Therefore I use often Singletons to avoid global data. But of course, as everything is overusable, this could be a overuse of the Singleton pattern. (Johshua Kerievsky calls this "Singletonitis" in his book "Refactoring to Patterns".)
因此,我经常使用单例来避免全局数据。但是,当然,由于一切都是可重用的,这可能是对单例模式的过度使用。(约翰舒亚·克里夫斯基(joh舒舒亚·克里夫斯基)在他的《模式重构》(重构to Patterns)一书中把这种现象称为“单发症”。)
UPDATE 2:
更新2:
(Sorry, but I cannot write comments, therefore this Update.)
(抱歉,我不能写评论,所以这次更新。)
Jalf wrote in his comment: "The gang of four were smoking something illegal when they wrote about the singleton pattern."
贾尔夫在他的评论中写道:“*在写单例模式的时候吸烟是违法的。”
Obviously, other C++ developers smoked interesting substances, too. For example, Herb Sutter (he served for over a decade as secretary and chair of the ISO C++ standards committee during the development of the second C++ standard, C++0x, and as lead architect of C++/CLI at Microsoft. Herb is currently the designer of the Prism memory model for Microsoft platforms and the Concur extensions to Visual C++ for parallel programming), wrote in C++ Coding Standards, Item 21:
显然,其他c++开发人员也使用了一些有趣的东西。例如,Herb Sutter(他在开发第二个c++标准c++ 0x期间担任ISO c++标准委员会的秘书和主席超过十年,并在微软担任c++ /CLI的首席架构师。Herb是目前微软平台的Prism内存模型的设计者,同时也是Visual c++的并行编程的Concur扩展,在c++的编码标准中写道,项目21:
"When you need such a (namespace level) variable that might depend upon another, consider the Singleton design pattern; used carefully, it might avoid implicit dependencies by ensuring that an object is initialized upon first access. Still, Singleton is a global variable in sheep's clothing, and is broken by mutual or cyclic dependencies."
“当您需要这样一个(名称空间级)变量时,可以考虑单例设计模式;小心使用,它可以通过确保在第一次访问时初始化对象来避免隐式依赖关系。不过,单例在绵羊的衣服上是一个全局变量,并且被相互或循环的依赖关系打破。
So, avoid global data, if you can. But if you have to use global data in separate translation units, Singleton should be an acceptable solution for enforcing a specific initialization sequence.
所以,如果可能的话,尽量避免使用全局数据。但是,如果您必须在单独的转换单元中使用全局数据,单例应该是执行特定初始化序列的可接受的解决方案。
Note that in the Java language global data does not even exist. Obviously, global data is substituted/emulated by the use of the Singleton design pattern.
注意,在Java语言中甚至不存在全局数据。显然,使用单例设计模式替代/模拟了全局数据。
(For I am working in my dayjob with a Java team, I strive for a maximal similarity of my C++ programs with Java programs. E.g, every class is situated in its own source file/translation unit.)
(因为我在Java团队工作,所以我希望我的c++程序与Java程序之间的相似性最大。E。g,每个类都位于它自己的源文件/翻译单元中。
#5
0
Not really a direct answer to your question, but something closely related to watch out for if you use both C and C++.
这并不是对你的问题的直接回答,但是如果你同时使用C和c++,你需要注意一些密切相关的问题。
In C++, unlike C, global variables which are declared "const" are implicitly local to the translation unit, AS IF "static" had been used.
在c++中,与C不同的是,被声明为“const”的全局变量在翻译单元中是隐式的,就像使用“静态”一样。
Example:
例子:
// file A
extern const int glob;
// file B
const int glob = 42;
This will work if you are using a C compiler but not with a C++ compiler. In C++, the glob variable in file B cannot be used from file A and the linker will generate an "unresolved reference" error.
如果您使用的是C编译器,而不是c++编译器,那么这将是可行的。在c++中,文件B中的glob变量不能从文件A中使用,链接器将生成一个“未解决的引用”错误。