铸造

时间:2017-02-02 04:00:51

标签: c semantics algol68

假设我们分别在Algol 68和C中有以下说明: ref int x := 5;(int*) x = 5;。它们的语义差异是什么?,它是一样的吗?因为我认为第二个说“x将指向一个常量”(它无法编译),第一个说“x将指向一个记忆”指向包含常量5“的另一个存储单元的单元格。这是正确的吗?如果没有,你能解释一下并举一些例子来理解这个吗?

3 个答案:

答案 0 :(得分:4)

我不假装成为Algol 68(或Algol 60)专家 - 我从未使用任何一种语言编写任何内容。

然而,维基百科Algol 68 mode declarations说:

  

然而,声明real x;只是ref real x = loc real;的语法糖。也就是说,x实际上是新生成的本地real变量的引用常量标识符

鉴于这个解释,问题是Algol片段:

ref int x := 5;

对应于(或多或少)C代码:

int *x = malloc(sizeof(*x));
*x = 5;

抛开错误检查和释放已分配内存的问题。

问题的C片段:

(int *)x = 5;

很大程度上没有意义 - 演员表的结果不是可修改的左值,你只能指定一个可修改的左值。如果重写为:

int x_data;
int *x = &x_data;
*(int *)x = 5;

然后它变为有效的C,尽管演员阵容完全是多余的。当然,也可以编写它来使用内存分配。在C中,使用x访问整数值(而不是指针)需要在C(*xx[0])中取消引用。相比之下,在Algol 68中,没有必要明确地取消引用变量x

虽然问题提到了“常数”几次,但我没有看到任何暗示代码中的持久性。值5被分配给位置中的变量。存储在该位置的值可以稍后通过另一个分配进行更改。

问题标题询问了关于强制转换的问题,但是我没有看到Algol代码中存在强制转换的证据,并且不清楚为什么在C代码中认为有必要使用强制转换。

答案 1 :(得分:3)

Algol 68根据具体情况(强,坚,弱,弱和软背景)提供许多隐式强制:cf Wikipedia & Algol68's Coercion Hierarchy

Algol68可以隐式处理:

  1. 扩大精度和尺寸(强)
  2. 联合不同类型(公司)
  3. 有针对性的解除引用(Meek和Weak)
  4. 程序化,去处理(软)
  5. C强化具有更多受限制的隐式投射:

    1. 仅限于暗示“扩大”'精度和floatint仅在某些情况下。扩展到数组需要指针和手动编码使用"&"操作者。
    2. 必须手动编码/创建联合。
    3. 在投射过程中没有解除引用(C强制编码器明确计算使用" *"取消引用指针的次数。 操作者)。
    4. 不带参数的过程必须按名称显式定义,并使用"()"操作者。
    5. 带输出的示例代码......

      文件:deref_and_cast.c

      #include <stdio.h>
      #include <stdlib.h>
      
      main(){
        auto int*** crrri;
        crrri=(int***)malloc(sizeof(int**));
        *crrri=(int**)malloc(sizeof(int*));
        **crrri=(int*)malloc(sizeof(int));
        ***crrri=255; /* coder to explicitly work out how many times dereference */
        printf("%5.1f\n",(float)***crrri); /* Again deref is muilt-explicit */
      }
      

      <强>输出:

      255.0
      

      档案:coerce_and_cast.a68

      #!/usr/bin/a68g --script #
      # -*- coding: utf-8 -*- #
      
      LOC REF REF REF INT crrri;
      REF REF REF REF INT(crrri):=HEAP REF REF INT;
      REF REF REF INT(crrri):=HEAP REF INT;
      REF REF INT(crrri):=HEAP INT;
      REF INT(crrri):=255; # targeted dereferencing (3x) depending on contect #
      printf(($"example meek coercion:"g(-5,1)l$,REAL(crrri)));
      

      隐式强制的层次结构示例

      PROC VOID raise exception = end; # Implicitly cast a "GO TO" to a PROC #
      
      # Soft: deprocedure a PROC to a VALUE #
      printf(($"Soft:"gl$,random)); # Implicit Coercion #
      printf(($"Soft:"gl$,REAL(random))); # Explicitly cast/deprocedure #
      
      # Weak: dereference pointer chain to a "name" (LHS in C lingo) #
      COMPL compl:= 0;
      re OF compl := crrri; # Implicit Coercion #
      REF REAL(re OF compl) := crrri; # Explicitly cast/dereference #
      printf(($"Weak:"g(-0,4)g(7,4)"i"l$,compl));
      
      # Meek: dereference to a value #
      printf(($"Meek:"gl$,sin(crrri))); # Implicit Coercion #
      printf(($"Meek:"gl$,sin(REAL(crrri)))); # Explicitly cast/dereference #
      
      # Firm: unite to a UNION #
      MODE IRC=UNION(INT,REAL,COMPL);
      OP SIN = (IRC z)IRC: (z|(INT i):sin(i),(REAL r):sin(r),(COMPL z):complex sin(z));
      printf(($"Firm:"gl$,SIN 1)); # Implicit Coercion #
      printf(($"Firm:"gl$,SIN IRC(1))); # Explicitly cast/unite #
      
      # Strong: widen to higher precision OR to an array #
      FLEX [0]BOOL bool array := BIN crrri; # Implicit Coercion #
      bool array := []BOOL(BIN crrri); # Explicitly cast/widen #
      printf(($"Strong:"$,$g$,bool array,$l$));
      
      end: SKIP
      

      <强>输出:

      example meek coercion:255.0
      Soft:+2.11679610884246e  -1
      Soft:+4.01945464342605e  -1
      Weak:255.0000+0.0000i
      Meek:-5.06391634924491e  -1
      Meek:-5.06391634924491e  -1
      Firm:+8.41470984807897e  -1
      Firm:+8.41470984807897e  -1
      Strong:FFFFFFFFFFFFFFFFFFFFFFFFTTTTTTTT
      

答案 2 :(得分:1)

Algol68对“名称”(与“标识符”不同)的含义采取了严格的方法。一个明显的结果是,Algol68在对象的类型/模式上倾向于具有比其他语言更多的引用。

因此INT是一个常量整数的模式(它甚至可能不需要在运行时分配内存)。 REF INT是“整数变量”的模式,而REF REF INT是“引用整数变量”的模式。

 INT x = 42; 
 REF INT y = LOC INT := x; 
 REF REF INT z = LOC REF INT := y;

LOC是一个“本地生成器”,实际上只是分配堆栈空间并返回其“名称”(即地址)。

(请注意,'='建立等效性,':='则是赋值)

熟悉语法所需要的是,这两个变量声明可以使用缩写形式:

INT y := x;
REF INT z := y;

但是y的模式仍然是REF INT,依此类推。IMO,缩写是个坏主意。

C当量

 #define x 42
 int y = x;
 int* z = &y;