Common Lisp THE不给出编译器警告

时间:2020-04-19 17:37:22

标签: common-lisp compiler-warnings

从当我更改以下形式时为THE函数(http://clhs.lisp.se/Body/s_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上测试了这些。

1 个答案:

答案 0 :(得分:2)

您误解了the的功能。规范用很多字告诉您:

the指定由form返回的值属于value-type指定的类型。 如果结果不是声明的类型,后果是不确定的。

(我的重点。)

换句话说,the的作用是让您对编译器说:“我保证这些东西具有这些类型,您可以为此编译适当的代码,而无需进行检查;如果那不是真的,那么我完全同意您可能需要放火烧掉并挖出剩下的一只眼睛。”

现在,著名的是,CMUCL及其派生工具(例如SBCL)采用了截然不同的类型检查方法。来自SBCL manual

SBCL编译器对待类型声明的方式与大多数其他Lisp编译器不同。根据默认的编译策略,编译器不会盲目相信类型声明,而是认为它们是有关应检查程序的声明:所有尚未被证明始终保持有效的类型声明都在运行时声明。

因此,系统将the视为有关类型的断言,如果尚未断言,则必须对其进行检查。我认为这是一致的,因为“未指明的后果”显然可以包括“以一种很好的方式引发异常”(个人而言,我更喜欢令人费解的编译器,但那只是我自己)。

但是,如果您想编写可移植的代码,则不应假定the是这样做的。相反,您需要接受它不会带来的风险,或者将check-typeassert之类的形式与类型检查一起用作断言。