关键字auto
, static
, extern
, register
, 和_Thread_local
在标准中被称为存储类说明符,但“对象”(这是我们通常称为“变量”的标准术语)没有存储类。相反,它们具有链接(外部、内部、无)和存储持续时间(静态、自动、线程)。此外,对象的任何声明可能是也可能不是定义。存储类说明符与声明对象的范围以及它是否具有初始化程序 ( int foo
vs int 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
术语“存储类说明符”有意与术语“存储持续时间”和“链接”不同,以提醒您说明符不会让您独立控制存储持续时间和链接。
该语言无法让您独立控制存储持续时间、链接和定义,因为不可用的组合没有意义。自动存储持续时间仅对在块范围内声明的变量有意义,而不是定义仅对具有外部链接的变量有意义(因为只有它们可以在另一个文件中定义)等等。
我离开了桌子register
,_Thread_local
因为它们很特别。 register
就像auto
除了它也意味着您不允许获取对象的地址。 _Thread_local
使变量的存储时间为“线程”并且不改变链接;它可以单独使用,也可以与extern
or一起使用static
,但将其与“auto”结合使用是违反约束的。如果您在块范围内单独使用它,我不确定它会做什么。