static关键字将全局变量的范围限制为该转换单元。
如果我在.h文件中使用static int x
并在每个其他文件中包含该.h文件,它们是否都属于同一个翻译单元?
那么,到处都不会出现x吗?
那么现在静态的作用是什么?
此外,是否有static const int x
的使用,其中x是全局变量?
默认情况下,并非所有const全局变量都是静态的
并且const变量的范围仅限于TU,即使它被限制在文件中的for循环中吗?
答案 0 :(得分:35)
如果你写
static const int x
在 .h 文件中, #include -s this .h 的每个翻译单元都有自己的私有变量{{1 }}
如果您希望每个人都能看到1个全局变量,那么您应该编写
x
.h 文件中的和
extern const int x;
在其中一个 .cpp 文件中。
如果您想让静态const int只对一个翻译单元可见 - 请不要在 .h 文件中提及它。
答案 1 :(得分:6)
如果我在.h文件中使用static int x并且每次都包含.h文件 其他文件,它们都不属于同一个翻译单元吗?
如果将某些东西声明为静态(不在类中,对于类static关键字具有不同的语义),则不能在其TU之外看到该静态变量。因此将它放在头文件中将导致包含该头的每个TU具有该静态变量的不同私有副本。
并且const变量的范围仅限于TU,即使它受限制 在文件中的for循环中?
NO。即使对于静态const值,范围也由它的声明决定。所以范围将受到括号的限制。
答案 2 :(得分:3)
每次翻译时你最终会得到该变量的私有副本,如果你把它放在那里会导致膨胀。在整个地方随机复制也没有任何意义。不,不行。
您可以在const int
块中声明namespace
;没关系。
答案 3 :(得分:1)
const
限定变量的可观察差异在于static
版本,每个翻译单元将获得一个副本,因此两个此类副本的地址比较可能会失败。
如果你从不使用const
变量的地址,任何现代编译器都应该能够使用该值并优化变量本身。在这种情况下,static
const
- 限定变量完全没问题。
答案 4 :(得分:0)
基本上,每个源文件以及所有包含的头文件都是单个翻译单元。因此,如果头文件中有静态变量,那么它在每个源文件(翻译单元)中都是唯一的,包含头文件。
答案 5 :(得分:0)
“静态全局”没有意义,它们在某种程度上是彼此相反的。
“全局”一词经常被误用于描述在文件范围内的任何函数之外声明的变量。但是,全局变量是具有外部链接的变量,可以由项目中的任何文件访问-因此是全局变量。
与外部链接相反的是内部链接,这意味着变量只能由声明其的翻译单元访问。转换单元,意味着一个.c
文件及其包含的所有标头(递归)。
static
是确保变量获得内部链接的保证。因此,其他转换将无法访问它或声明引用它的extern
变量。
如果您在头文件中声明一个static
变量,将会发生不止一个转换单元使用该名称的单独变量的情况。该代码可以很好地编译,尽管聪明的链接器会注意到这一点并给出链接器错误。这些链接器错误通常是非描述性的,很难跟踪。
这使我们获得以下最佳实践:
为防止此类错误,请始终在所有标头文件中使用“标头防护”:
#ifndef MYHEADER_H
#define MYHEADER_H
/* contents of header */
#endif
在文件范围内声明的所有变量都应声明为static
,以进行私有封装并减少命名空间的混乱。同样,应避免使用extern
,因为它会导致不良的设计和意大利面条式的编程。