普通Lisp的THE没有给出任何编译器警告。

问题描述 投票:0回答:1

从所举的例子来看。THE 功能 (http:/clhs.lisp.seBodys_the.htm。),当我改变以下形式

(the (values integer float) (truncate 3.2 2))

(the (values integer integer) (truncate 3.2 2))

我仍然没有收到任何编译器警告,而 (the integer 1.2) 给予

;编译器警告: ;在0位置的匿名lambda形式中:在(THE INTEGER 1.2)中违反了类型声明。

谁能解释一下为什么上面的内容不会产生警告?我在CCL上测试这些。

common-lisp compiler-warnings
1个回答
2
投票

你误解了 the 的。 规范用这么多话告诉你。

the 指定由form返回的值是由value -type指定的类型。如果任何结果不是声明的类型,其后果是未定义的。

(我的强调。)

换句话说,什么 the 的作用是允许你对编译器说:"我保证这些东西有这些类型,你可以编译适当的代码,而不需要检查;如果这不是真的,那么我完全接受你可能需要把我的头发烧掉,把我剩下的一只眼睛挖出来"。

现在,著名的CMUCL和它的衍生产品如SBCL采用了一种相当不同的类型检查方法。 从 SBCL手册:

SBCL编译器对待类型声明的方式与大多数其他Lisp编译器不同。在默认的编译策略下,编译器并不盲目相信类型声明,而是认为它们是关于程序的断言,应该进行检查:所有没有被证明总是成立的类型声明都会在运行时被断言。

因此,系统会将 the 作为一个关于类型的断言,如果还不知道它是真的,就必须被检查。 我认为,这是符合要求的,因为 "未指定的后果 "显然可以包括 "以一种很好的方式引发异常"(我个人更喜欢挖眼的编译器,但这只是我的看法)。

但如果你想写可移植的代码,你就不应该假设说 the 做到这一点。 相反,你需要接受它没有的风险,或者使用一些形式,如 check-typeassert 以类型检查作为你所断言的事情。

© www.soinside.com 2019 - 2024. All rights reserved.