1

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

4

3 回答 3

4

我不会假装自己是Algol 68(或Algol 60)专家——我从来没有用任何一种语言编译过任何东西。

然而,关于Algol 68 模式声明的维基百科说:

但是,声明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 代码中认为强制强制强制转换是必要的。

于 2017-02-02T18:19:38.033 回答
4

Algol 68 有许多可用的隐式强制,具体取决于上下文(强、坚定、温和、弱和软上下文):cf Wikipedia & Algol68's Coercion Hierarchy

Algol68 可以隐式处理:

  1. 扩大精度和尺寸(强)
  2. 联合不同类型(公司)
  3. 有针对性的解除引用(Meek 和 Weak)
  4. 处理,去处理(软)

C 强制转换有更多限制的隐式强制转换:

  1. 仅限于隐含的“扩大”精度,并且仅限floatint在某些情况下。扩大到数组需要使用“&”运算符的指针和手动编码。
  2. 必须手动编码/创建联合。
  3. 强制转换期间没有取消引用(C 强制编码器使用“*”运算符显式计算取消引用指针的次数)。
  4. 没有参数的过程必须由名称显式定义并使用“()”运算符调用。

带输出的示例代码...

文件: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
于 2017-04-03T04:00:17.733 回答
2

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;
于 2019-01-04T03:46:14.757 回答