第五章 类型检查

编译器必须检查源程序是否满足源语言在语法和语义两个方面的约定。这种检查这种检查称为静态检查(以区别在目标程序运行时的动态检查),它诊断和报告程序错误。静态检查的例子如:类型检查、控制流检查、唯一性检查、关联名字检查。

5.1 类型在程序设计语言中的作用

5.1.1 执行错误和安全语言

程序运行时的执行错误分成两类:

  • 会被捕获的错误(trapped error)
    例:非法指令错误、非法内存访问、除数为零
    引起计算立即停止
  • 不会被捕获的错误(untrapped error)
    例:下标变量的访问越过数组末端的数据
    例:跳到一个错误的地址,该地址开始的内存正好代表一个指令序列
    错误可能会有一段时间未引起注意
  • 良行为的程序
    不同场合对良行为的定义略有区别
    例如,没有任何不会被捕获错误的程序
  • 安全语言
    任何合法程序都是良行为的
    通常是设计一个类型系统,通过静态的类型检查来拒绝不会被捕获错误
    但是设计一个类型系统,它正好只拒绝不会被捕获错误是非常困难的
  • 禁止错误(forbidden error)
    不会被捕获错误集合 + 会被捕获错误的一个子集
    为语言设计类型系统的目标是在排除禁止错误
  • 良行为程序和安全语言也可基于禁止错误来定义

    5.1.2 类型化语言和类型系统

  • 类型化的语言
    • 变量的类型
      变量在程序执行期间的取值范围
    • 类型化的语言
      变量都被给定类型的语言
      并且表达式、语句等语法结构的类型都是可以静态确定的
      例如,类型boolean的变量x在程序每次运行时的值只能是布尔值,not (x)总有意义
    • 未类型化的语言
      不限制变量值范围的语言:
      一个运算可以作用到任意的运算对象,其结果可能是一个有意义的值、一个错误、一个异常或一个语言未加定义的结果,例如:LISP语言。
    • 显式类型化语言
      类型是语法的一部分
    • 隐式类型化的语言
      不存在隐式类型化的主流语言,但可能存在忽略类型信息的程序片段,例如不需要程序员声明函数的参数类型
  • 类型系统
    • 语言的组成部分,由一组定型规则(typing rule)构成,这组规则用来给各种语言构造指派类型
    • 设计类型系统的根本目的是用静态检查的方式来保证合法程序运行时的良行为
    • 类型系统的形式化
      类型表达式、定型断言、定型规则
    • 类型检查算法
      通常是静态地完成类型检查
  • 良类型的程序
    • 没有类型错误的程序
  • 合法程序
    • 良类型程序(若语言定义中无其它方式表示的约束)
  • 类型可靠(type sound)的语言
    • 所有良类型程序(合法程序)都是良行为的
    • 类型可靠的语言一定是安全的语言

      5.1.3 类型化语言的优点

      从工程的观点看,类型化语言有下面一些优点
  • 开发的实惠
    • 较早发现错误
    • 类型信息还具有文档作用
  • 编译的实惠
    • 程序模块可以相互独立地编译
  • 运行的实惠
    • 可得到更有效的空间安排和访问方式

      5.2 描述类型系统的语言

  • 类型系统主要用来说明程序设计语言的定型规则,它独立于类型检查算法
  • 定义一个类型系统,通常的设计目标是存在有效的类型检查算法
  • 类型系统的基本概念可用于各类语言,包括函数式语言、命令式语言和并行语言等

    5.3 简单类型检查器的说明

    5.4 多态函数

  • 多态函数
    • 允许变元有不同的类型
    • 体中的语句可以在变元类型不同的情况下执行(区别于重载的特征)
  • 多态算符
    • 用于以不同类型的变元执行的代码段
    • 例如:数组索引、函数作用、通过指针间接访问
    • C语言手册中关于指针&的论述是:如果运算对象的类型是‘…’,那么结果类型是指向‘…’的指针”

      5.5 类型表达式的等价

      5.6 函数和算符的重载