【发布时间】:2015-07-01 20:06:40
【问题描述】:
我知道如果安全设置较低,Common Lisp 可以使用类型注释作为优化辅助,并且不被检查。例如,该程序运行并打印数字和字符串,没有任何类型错误。 (当安全 >= 1 时,我只会在 SBCL 中收到类型错误)
(declaim (optimize
(speed 3)
(safety 0)))
(defun f (x)
(declare (type fixnum x))
x)
(format t "1 ~A~%" (f 17))
(format t "2 ~A~%" (f "asd"))
我现在想知道如果安全性设置为零并且不遵守类型注释,是否有可能创建一个执行令人讨厌的事情的程序。诸如从一种类型转换为另一种类型(如 C 类型转换)和其他类型的未定义行为。
到目前为止,我还没有找到一个可以做到这一点的例子。我尝试了使用类型化数组的这个示例的变体,但它们都没有导致类型转换行为。
(declaim (optimize
(speed 3)
(safety 0)
))
(defun f ()
(let ((arr (make-array '(5)
:element-type 'fixnum
:initial-contents (list 1 2 3 4 5))))
(declare (type (vector fixnum 5) arr))
(setf (aref arr 0) "hello")
(aref arr 0)))
(format t "a1 ~A~%" (f))
在 CLISP 中,该程序打印“hello”,而不对 int 进行类型转换,而在 SBCL 中,程序中止并出现 SIMPLE-TYPE-ERROR 错误。
如果我不尊重我的类型声明,有没有办法创建一个会导致恶魔从我鼻子里冒出来的 Common Lisp 程序?
【问题讨论】:
-
如果这是一个恶魔,我不知道,但在 CCL 中,您的程序会打印:
a1 6614253635515。 -
对于 SBCL,类型推断知道本地创建值的类型。 sds 的回答显示了解决这个问题的好方法。
-
@Xach:你能举个例子吗?在 SBCL 上运行 sds 的示例给了我一个
#(1 2 3) is not a LIST错误,而不是我想要的无意义值。
标签: types common-lisp declare