当前位置:  开发笔记 > 编程语言 > 正文

头文件中的变量声明 - 静态与否?

如何解决《头文件中的变量声明-静态与否?》经验,为你挑选了5个好方法。

当重构一些时,#defines我遇到了类似于C++头文件中的以下声明:

static const unsigned int VAL = 42;
const unsigned int ANOTHER_VAL = 37;

问题是,静态会产生什么不同,如果有的话?请注意,由于经典#ifndef HEADER #define HEADER #endif技巧(如果重要),不可能多次包含标题.

VAL如果标题包含在多个源文件中,静态是否只创建了一个副本?



1> bk1e..:

文件范围变量上的staticextern标记确定它们是否可以在其他翻译单元(即其他.c.cpp文件)中访问.

static给出变量内部链接,将其隐藏在其他翻译单元之外.但是,具有内部链接的变量可以在多个翻译单元中定义.

extern给出可变外部链接,使其对其他翻译单元可见.通常,这意味着变量必须仅在一个转换单元中定义.

默认值(当您未指定static或时extern)是C和C++不同的区域之一.

在C中,extern默认情况下文件范围的变量是(外部链接).如果你使用C,VALstaticANOTHER_VALextern.

在C++中,static默认情况下,文件范围的变量是(内部链接),如果是const,则extern默认情况下(如果不是).如果您使用C++,无论是VALANOTHER_VALstatic.

从C规范的草案:

6.2.2标识符的链接... -5-如果函数的标识符声明没有存储类说明符,则确定其链接与使用存储类说明符extern声明的链接完全相同.如果对象的标识符声明具有文件范围而没有存储类说明符,则其链接是外部的.

从C++规范的草案:

7.1.1 - 存储类说明符[dcl.stc] ... -6-在没有存储类说明符的命名空间作用域中声明的名称具有外部链接,除非由于先前的声明而具有内部链接且未提供声明const.声明为const且未显式声明为extern的对象具有内部链接.



2> Justsalt..:

static意味着将为其VAL包含的每个源文件创建一个副本.但这也意味着多个包含将不会导致多个定义VAL将在链接时发生冲突.在C中,没有static你需要确保只有一个源文件定义,VAL而其他源文件声明它extern.通常可以通过在源文件中定义它(可能使用初始化程序)并将extern声明放在头文件中来实现.

static 全局级别的变量只能在他们自己的源文件中看到,无论他们是通过包含还是在主文件中.


编者注:在C++中,声明中conststatic没有extern关键字也没有关键字的对象是隐含的static.


@ Brent212编译器不知道声明/定义是来自头文件还是主文件.所以你希望徒劳无功.如果某人愚蠢并且在头文件中放置一个静态定义并且它包含在两个源中,那么将有两个VAL副本.

3> slicedlime..:

静态意味着每个文件只能获得一个副本,但与其他人不同的是,这样做是完全合法的.您可以使用一个小代码示例轻松测试:

test.h:

static int TEST = 0;
void test();

test1.cpp:

#include 
#include "test.h"

int main(void) {
    std::cout << &TEST << std::endl;
    test();
}

测试2.cpp:

#include 
#include "test.h"

void test() {
    std::cout << &TEST << std::endl;
}

运行此命令可以获得此输出:

0x446020
0x446040


谢谢你的例子!

4> 小智..:

constC++中的变量具有内部链接.所以,使用static没有效果.

const int i = 10;

one.cpp

#include "a.h"

func()
{
   cout << i;
}

two.cpp

#include "a.h"

func1()
{
   cout << i;
}

如果这是一个C程序,你会得到"多重定义"错误i(由于外部链接).


好吧,使用`static`会产生这样的效果:它可以巧妙地表达对编码内容的意图和意识,这绝不是一件坏事.对我来说,这就像在覆盖时包含`virtual`:我们没有必要,但事情看起来更直观 - 并且与其他声明一致 - 当我们这样做时.

5> Mark..:

此级别代码的静态声明意味着变量仅在当前编译单元中可见.这意味着只有该模块中的代码才能看到该变量.

如果您有一个声明变量static的头文件,并且该头包含在多个C/CPP文件中,那么该变量将对这些模块"本地".对于包含标题的N个位置,将有N个副本.他们完全没有关系.任何源文件中的任何代码都只引用该模块中声明的变量.

在这种特殊情况下,'static'关键字似乎没有提供任何好处.我可能会遗漏一些东西,但似乎并不重要 - 我以前从未见过这样的事情.

至于内联,在这种情况下变量很可能内联,但这只是因为它被声明为const.编译器可能更可能内联模块静态变量,但这取决于情况和正在编译的代码.无法保证编译器会内联"静态".

推荐阅读
重庆制造漫画社
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有