关于作用域和生存期浅析

作用域:

作用域的作用:避免名字冲突。

作用域的分类全局作用域,局部作用域,函数作用域,函数原型作用域,文件作用域,名字空间作用域,类作用域。


 

全局作用域:即程序的作用域。

局部作用域:代码块中的{}

函数原型作用域:即函数声明(非定义)是参数列表形参的作用域,该作用域仅仅在形参列表,故一点也不重要。

函数作用域:只有用作goto语句的标号才具有函数作用域!!!函数体{}是局部作用域!!!

文件作用域:在当前文件可见的标识符具有文件作用域,如static声明的函数或全局变量

类作用域:定义类会引入一个独立的作用域,基类的作用域大于子类的作用域。



注意:C++函数是不能定义在局部作用域的,其对外不可见,不能被调用,没有意义,所以c++不允许函数嵌套定义,没有局部函数的存在,因此也就不能实现函数作用域闭包,但可以使用模板的非类型参数来实现闭包。



----------


名字解析:

名字解析:把名称和声明关联的过程,即给出该名称意义的过程。

名称的解析是由内向外的,所以外围作用域中声明的名称会被嵌套作用域中的名称隐藏。

可以使用::作用域运算符引用被隐藏的全局名称,注意,不是外围作用域,类似python中的,global和nonlocal声明

函数重载的前提是在统一作用域内,和名称解析是完全不相同的概念,但是既可以使用在同一作用域中声明某一特定的重载函数来避免函数重载,又可以使用在统一作用域声明多个同名函数来实现函数重载,所以,重载函数是指在同一作用域声明的同名函数,而非定义。




----------
存储期:即对象的生命期,占用内存的时间

存储期分为:静态存储期,自动存储期,动态存储期(动态分配堆上的内存)

链接性:用于描述标识符在代码间,文件源码间,编译目标模块,库之间的共享情况。

关于链接性的意义:现代编译器一般都是按照文件为编译单元来进行编译的,所以在编译阶段各个文件中的全局变量是互不相见的,即在编译阶段全局变量的作用域仅仅被局限在文件内部,也就是说在在编译阶段,各个文件中出现同名的全局变量是不会出现冲突的。但是在链接阶段,将各个文件合为一体,只是不同文件中的同名变量就会冲突,由此可见,链接阶段的全局作用域从文件作用域扩大到了程序作用域。扩大了作用域


链接性分为:内部链接,外部链接,无链接。

外部链接:标识符可以在所有文件中共享,使用,作用域为全局的。

内部链接:标识符只能在定义它的文件内使用,共享,作用域为全局。

无链接:标识符只能在某个函数或局部作用域内使用或共享。

标识符的链接性由 标识符所引用的实体(变量,函数),标识符的位置(局部还是全局,)和存储类型区分符(static,extern)三者共同决定。

===作用域,生存期,链接性三者是不同的概念,作用域描述标识符的可见范围,生存期描述变量的占用内存的期限,链接性描述标识符的共享情况。因此不同作用域的标识符可能具有不同的存储持续性,同时还具有不同的链接性。



关于程序中变量的内存的布局和分布,在编译时基本上就已经确定了,当然是没有映射到物理进程的地址空间,更别提物理内存,但是确实布局完成了的,是采用地址偏移来完成的,就像可以在航海的船,船的结构和配件的组装其实是在经历风雨浪花之前就已经确认好了,和是在湖上,江山,海上航行无关,比如船的宽度为10米,船底距离船板的高度为8米,夹层地板距离船底高度为5米,等等....然后再设计师船板距离海水的高度是和设计没有关系的。

函数,全局变量,static变量都具有静态存储持续期。


链接性的创建:
    
创建外部链接性:在定义全局变量的时候使用extern修饰。

创建内部链接性:具有内部链接性的变量在全局作用域中应该具有static或const加以说明。


各种变量的默认链接性:
    
    1.全局变量默认具有外部链接性
    2.自动存储变量只能是无链接性
    3.使用const声明的全局变量默认其链接性为内部链接性。
    4.要使const修饰的全局变量的链接性是外部链接性必须使用extern修饰,并对其进行初始化(定义),若不进行初始化,这表示extern声明。


static
    
    static说明的标识符具有是静态的,静态变量的作用范围既可以是文件作用域,也可以是全局的,其实在
    反汇编中static说明变量和只用const说明是相同的实现。 其次static定义只会初始化一次,推广到多线
    程的时候,如果一个函数中出现静态变量的时候,没有保护的访问,那么该函数是不可重入的。 因为
    static变量作为一个内存资源,是在整个程序生存期存在,然后其存在于程序的数据段,并不在函数的堆
    栈上,不是某一线程私有,而是所有线程所共享,所以是会产生data race的。


 

你可能感兴趣的:(c/c++,编译原理)