我经常在需要修改的驱动程序代码中看到静态结构声明。
我尝试了解为什么会声明structs
并进行此操作的动机。
请问有谁能帮助我理解这个问题吗?
static
关键字有不同的作用,取决于它所应用的上下文。
显然其他答案似乎都没有提到的一点是: static
还指定了对象的 存储期限,与 自动变量(局部变量)和 分配内存(由 malloc 等函数返回的内存)一起。
具有静态存储期的对象在 main() 函数开始之前进行初始化,可以使用指定的初始化程序进行初始化,如果没有指定,则像将 0 赋给它一样进行(对于结构体和数组,这适用于每个成员和递归操作)。
第二个属性 static
为标识符设置的是其 链接性,这是一个在链接时使用的概念,告诉链接器哪些标识符引用相同的对象。 static
关键字使标识符具有 内部连接性,这意味着它不能引用另一个翻译单元中相同名称的标识符。
至于我之前看过的所有松散的答案,需要严谨一点:静态变量无法在声明它的文件中的任何位置引用。它的作用域只在其声明(可以在函数定义之间)到源文件的结尾--甚至更小,到封闭块的结尾。
结构体 变量
对于像static struct S s;
这样的结构体变量,已经在以下网址广为讨论:What does "static" mean in C?
结构体 定义:无影响:
static struct S { int i; int j; };
就是完全相同的意思:
struct S { int i; int j; };
因此永远不要使用它。如果您这样做,GCC 4.8会发出警告。
这是因为结构定义没有存储,并且不像变量和函数一样在目标文件中生成符号。只需尝试编译和反汇编:
struct S { int i; int j; };
int i;
随着:
gcc -c main.c
nm main.o
你会发现没有S
符号,但有一个i
符号。
编译器只是使用定义在编译时计算字段的偏移量。
这就是为什么结构体定义通常包含在头文件中的原因:即使多次包含,它们也不会生成多个单独的数据。
enum
也是如此。
C++结构体定义:在C++11中已过时
C++11 N3337标准草案附录C 7.1.1:
更改:在C ++中,static或extern限定符只能应用于对象或函数的名称 在类型声明中使用这些限定符在C ++中是非法的。在C中,当用于类型声明时,这些限定符将被忽略。
static
,它只在该翻译单元中可见(如果是全局声明),或者在函数内部声明时保留其值以供调用使用。struct
的 static
修饰符将结构的可见范围限制在当前翻译单元(即文件)内。
static
变量的要点是,有时候定义一个参数或一组参数值来“重置”这些变量是很有用的。将所有对某些变量的访问限制在一个函数内可以更容易地理解它们,但如果在编写函数时没有提供重置它们的方法,那么如果以后需要多次“从头开始”运行该函数(在某些测试场景中可能很常见),添加重置功能可能会很困难。 - supercat