每个变量在C中都有一个存储类吗



人们可能会天真地认为它有,因为通常在没有提供存储类关键字时假设auto

不过,对于文件范围的变量,在其前面放一个auto会产生错误。

#include <stdio.h>
auto int x;
int main(void){
x = 7;
printf("x = %d", x);
}

Clang抱怨:

3:10: error: illegal storage class on file-scoped variable
auto int x;

声明没有任何存储类关键字的x并编译:

#include <stdio.h>
int x;
int main(void){
x = 7;
printf("x = %d", x);
}

现在我想知道在上面的例子中x有什么存储类?它有名字吗?

关键字autostaticexternregister_Thread_local在标准中被称为存储类说明符,但"对象"(这是我们通常称之为"变量"的标准术语)没有存储类。相反,它们具有链接(外部、内部、无)和存储持续时间[静态、自动、线程]。此外,对象的任何声明都可能是定义,也可能不是定义。存储类说明符,以及声明对象的作用域,以及它是否具有初始值设定项(int fooint foo = 3),控制这些属性。用一个表来展示这是如何工作的最简单方法:

sc-specifier scope initialized   linkage    storage duration    is a definition
------------ ----- -----------   -------    ----------------    ---------------
auto         file  no            [constraint violation]
auto         file  yes           [constraint violation]
auto         block no            none       automatic           yes
auto         block yes           none       automatic           yes
none         file  no            external   static              yes
none         file  yes           external   static              yes
none         block no            none       automatic           yes
none         block yes           none       automatic           yes
static       file  no            internal   static              yes
static       file  yes           internal   static              yes
static       block no            none       static              yes
static       block yes           none       static              yes
extern       file  no            external   static              no
extern       file  yes           external   static              yes
extern       block no            external   static              no
extern       block yes           external   static              yes

术语"存储类说明符"有意与术语"存储持续时间"one_answers"链接"不同,以提醒您,说明符不能独立控制存储持续时间和链接。

该语言不能让您独立控制存储持续时间、链接和定义,因为不可用的组合没有意义。自动存储持续时间只对在块范围内声明的变量有意义,而不是一个定义只对具有外部链接的变量有道理(因为只有它们可以在另一个文件中定义),等等

我把register_Thread_local排除在表之外,因为它们很特别。registerauto一样,只是它也意味着不允许获取对象的地址。_Thread_local使变量的存储持续时间为"线程",不改变链接;它可以单独使用,也可以与externstatic一起使用,但将其与"auto"组合会违反约束。如果您在块范围内单独使用它,我不确定它会做什么。

来自C标准§6.2.4第3段:

一个对象的标识符在声明时没有存储类说明符_Thread_local,,并且带有外部或内部链接或带有存储类说明符static,该对象具有静态存储持续时间。它的生存期是程序的整个执行过程,并且在程序启动之前,它存储的值只初始化一次。

强调挖掘。背面参考§6.2.2第5段:

如果函数的标识符声明没有存储类说明符,则确定其链接的方式与使用存储类说明符extern声明的方式完全相同。如果对象的标识符声明具有文件作用域且没有存储类说明符,则其链接是外部的

再次强调挖掘。

因此,全局变量默认情况下具有静态存储持续时间。即使没有标准来保证这一点,它也是唯一对全局变量有意义的存储持续时间类型。

每个变量在C中都有一个存储类吗?

是的,尽管标准实际上使用了术语"存储持续时间"。这是一样的,而且标准对关键字autostatic等使用了术语"存储类说明符",这一点也有点不一致

人们可能会天真地认为它有,因为当没有提供存储类关键字时,通常会假设自动。

否。绝对不是。对于函数和在文件范围内声明的任何内容,默认值为extern。只有在块作用域中声明的对象的标识符默认为auto

不过,对于文件范围的变量,在它们前面放一个auto会产生错误。

应该如此。该标准明确规定

存储类说明符autoregister不应出现在外部声明的声明说明符中。

[C11,第6.9/2]

在没有任何存储类关键字的情况下声明x,并编译[……]

当然。

现在我想知道在上面的例子中x有什么存储类?它有名字吗?

它的存储类是与关键字extern相对应的存储类。正如我已经说过的,这是文件范围声明的默认值。但是,尽管该标准使用了术语"存储类说明符",但它并没有将"存储类"作为一个独立的概念。它说话而不是存储持续时间。所有具有外部或内部链接的变量都有静态存储持续时间,这意味着它们在程序的整个生命周期中都存在。

相关内容

  • 没有找到相关文章

最新更新