存储类,存储持续时间,文件范围,生命周期,链接混淆

时间:2013-07-22 09:52:57

标签: c++ static scope

当谈到C++/C变量时,标准ISO文档会提及storage classstorage durationfile scopelifetime,和linkage

我想了解基本线索以及它们如何相互关联。但在阅读ISO文档后,我找不到这些概念的清晰逻辑图。

你可以帮忙澄清一下吗?我希望我能用这些概念来分析我的编程问题。

ISO documents部分:

  • C99 6.7.1存储类说明符
  • C99 6.11.2标识符的链接
  • C ++ 2003 7.1.1存储类说明符
  • C ++ 2003 7.5链接规范

2 个答案:

答案 0 :(得分:3)

  

存储类说明符是声明语法的decl-specifier-seq的一部分。它们控制声明引入的名称的两个独立属性:存储持续时间及其链接存储类说明符:

     
      
  • auto - 自动存储持续时间(直到C ++ 11)
  •   
  • register - 自动存储时间。还提示编译器将变量放在处理器的寄存器中(不建议使用)
  •   
  • static - 静态或线程存储持续时间和内部链接
  •   
  • extern - 静态或线程存储持续时间和外部链接
  •   
  • thread_local - 线程存储持续时间(自C ++ 11起)
  •   
     

存储持续时间

     
      
  • automatic存储时间。变量在封闭代码块的开头分配,并在末尾解除分配。所有非全局变量都具有此存储持续时间,但声明为staticexternthread_local的变量除外。
  •   
  • static存储时间。程序开始时分配变量,程序结束时分配变量。只存在一个变量实例。所有全局变量都具有此存储持续时间,以及使用staticextern声明的持续时间。
  •   
  • thread存储时间。线程开始时分配变量,线程结束时分配变量。每个线程都有自己的变量实例。只有声明为thread_local的变量才具有此存储持续时间。 thread_local可与staticextern一起显示以调整关联。   (自C ++ 11起)
  •   
  • dynamic存储时间。通过使用动态内存分配函数为每个请求分配和释放变量。
  •   
     

<强>联动即可。表示对象,引用,函数,类型,模板,命名空间或值的名称可以具有链接。如果名称具有链接,则它引用与另一个范围中的声明引入的相同名称相同的实体。如果在多个范围内声明了具有相同名称的变量,函数或其他实体,但没有足够的链接,则会生成该实体的多个实例。

     

以下链接得到承认:

     
      
  • 无链接。该名称只能从其所在的范围引用。
  •   
  • 内部链接。可以从当前翻译单元的所有范围引用该名称。
  •   
  • 外部链接。该变量可以从其他翻译单元的范围引用。
  •   

Reference.

答案 1 :(得分:0)

虽然我对这些概念有直观的理解,但我对他们的真实含义非常好奇;规则是什么以及为什么它们就是这样。

所以我写了一篇关于它的full blog post,这篇文章虽然没有成为标准,但却更加简单易懂。

以下是主要见解:

(C中的对象是变量或函数)

  

声明的范围是代码的一部分   声明被看到并可以使用。

     

请注意,这并未说明对象是否与之关联   声明可以通过代码的其他部分访问   另一个宣言!

     

我们通过其内存识别唯一对象:变量的存储   或功能代码。

     

持续时间表示与声明关联的对象   在整个程序的执行过程中持续存在(静态持续时间)或是否已分配   输入声明范围时动态(动态持续时间)。

     

链接是决定同一对象的多个声明的原因   引用相同的对象,或分开的对象。

关于链接,如果我们简化一下:

  • 无链接:声明引用唯一对象
  • 内部链接:编译单元中的所有声明都引用同一个对象
  • 外部链接:程序中所有带外部链接的声明都引用同一个对象

最后,一个方便的规则:

  

可以使用确定任何声明的链接和持续时间   只有三条规则(大多数先例规则优先):

     
      
  • 在函数中,没有extern的声明没有链接。

  •   
  • 在函数中,没有externstatic的声明具有自动持续时间。在任何范围内的任何其他声明都具有静态   持续时间。

  •   
  • 在编译单元中,如果存在具有static存储类说明符的声明,则对象具有内部链接。这个   声明必须在任何extern声明之前发生   不能没有存储类说明符的任何声明(或者   编译错误随之而来)。否则,他们有外部联系。

  •   

我希望这有帮助!