【问题标题】:structural equivalence vs name equivalence结构对等 vs 名称对等
【发布时间】:2010-12-20 02:17:34
【问题描述】:

我似乎无法准确理解名称对等是什么。我很确定我的结构已经下降。我的教授举的一个例子是这样的:

 Type TI=integer
 Type TTI=TI

 a=integer
 b=TTI
 f= ref float
 g= ref float

a 和 b 都是结构和名称等价的,而 f 和 g 只是结构上等价的。我不明白为什么 a 和 b 名称等价,但 f 和 g 不是。

【问题讨论】:

    标签: type-equivalence


    【解决方案1】:

    类型相等

    诸如赋值之类的基本操作的含义(在 C 中用 = 表示)在语言定义中指定。因此,例如,诸如

    之类的语句的含义
    x = y;
    

    这里对象y的值被复制到变量x的内存位置。

    但是,在翻译器可以接受诸如赋值之类的操作之前,通常两个操作数的类型必须相同(或者可能以某种其他指定的方式兼容)。

    因此,语言翻译者必须决定在某些情况下两种类型是否相等。我们现在考虑说两种类型“相等”(或等价)是什么意思。

    有两种标准方法可以确定两种类型是否相同:名称等价结构等价

    名称等价是最直接的:当且仅当它们具有相同的名称时,两个类型才相等。因此,例如,在代码中(使用C 语法)

       typedef struct {
               int data[100];
               int count;
               } Stack;
    
       typedef struct {
               int data[100];
               int count;
               } Set;
    
       Stack x, y;
       Set r, s;
    

    如果 name equivalence 在语言中使用,那么 xy 将属于同一类型,rs 将属于同一类型,但类型xy 的类型不等同于 rs 的类型。这意味着诸如

    之类的语句
       x = y;
       r = s;
    

    会是有效的,但是诸如

    之类的陈述
       x = r;
    

    无效(即不会被翻译人员接受)。

    使用结构等价两个类型相等当且仅当它们具有相同的“结构”,可以用不同的方式解释。
    严格的解释是这两种类型的每个组件的名称和类型必须相同,并且必须在类型定义中以相同的顺序列出。
    一个不太严格的要求是组件类型必须相同并且在两种类型中的顺序相同,但是组件的名称可以不同。

    再看上面的例子,使用 structural equivalenceStackSet 这两种类型会被认为是等价的,这意味着翻译者会接受诸如

    之类的语句
    x = r;
    

    (注意C 不支持结构等价,上面的赋值会报错。)

    【讨论】:

    • 非常有用的信息,但是链接坏了,能补一下吗?谢谢。
    • 抱歉,该链接不再有效。
    【解决方案2】:

    考虑下面的两个定义。

    type student = record
        name, address : string
        age : integer
    
    type school = record
        name, address : string
        age : integer
    
    x : student;
    y : school;
    

    在上面的例子中,变量 x 和 y 在名称等价下将被认为具有不同的类型: x 使用在第 1 行声明的类型; y 使用在第 4 行声明的类型。名称等价是基于这样的假设:如果程序员努力编写两个类型定义,那么这些定义可能意味着表示不同的类型。 (我不确定你给出的例子)

    参考:Programming Languages Pragmatics,M.L.斯科特

    【讨论】:

      【解决方案3】:

      如果您考虑编译器可能用来表示类型的内部数据结构,那么名称等效的概念最有意义。假设类型被表示为指向数据结构的指针。此外,假设我将类型等价检查实现为简单的指针比较(例如名称等价)。像integerfloat 这样的原始类型将存储在一些全局环境中,因为它们的数量是有限的。此外,如果我将integerinteger 进行比较,则可以保证它们是等价的,因为它们指向同一个结构,这得益于这种全局环境。

      但是,由于ref 不是类型构造函数,也不是原子类型,我可以使用它来创建无限多种类型(例如ref floatref ref float 等)。所以我们不能将它们全部存储在全球环境中。编译器可以用来管理这些类型的一种简单策略是,每当遇到类型构造函数时分配一个新结构,我们为该类型分配一个新数据结构。所以ref float 的实例会产生一个新的数据结构,而ref float 的另一个实例会产生一个全新的、不同的数据结构。指针比较失败,因此它们的名称不等价。

      还有一个难题,那就是赋值运算符的语义。这种类型别名是编译器中的简单指针复制,所以如果我写A=BA 的名称总是等同于B。但是,重申一下,F A 的名称不等同于 F A 的另一个实例!

      【讨论】:

        【解决方案4】:

        在名称类型等价中,如果两个变量在同一个声明中或在使用相同类型名称的声明中定义,则它们具有相同的类型。因此,您示例中的变量 'f''g' 是等价的。但是,变量'a''b' 不是等价的,因为它们具有不同的类型名称。 此外,在结构类型等价下,如果两个变量具有相同的结构,则它们具有相同的类型。因此,变量'a''b' 是等价的,变量'f''g' 也是等价的,因为显然同名的类型具有相同的结构。

        参考:Sebesta,《编程语言概念》,第 10 版。

        【讨论】:

          【解决方案5】:

          a 和 b 是别名,这就是它们名称等价的原因。 f 和 g 不是,所以它们不是名称等价的。

          【讨论】:

            【解决方案6】:

            别名:多个名称引用同一个对象(即同一个内存位置可以使用不同的名称访问)

            a 和 b 是别名,而 f 和 g 指的是恰好都是 'ref float' 的不同对象

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-07-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-05-09
              相关资源
              最近更新 更多