我试图运行光线追踪代码形式保罗·格雷厄姆的 ANSI Common Lisp的的OS X上使用与OpenMCL泥(当然,现在被称为CCL)。在该代码中,有其值是一个结构决定的常数,并且当我调用任一煤泥编译并加载文件煤泥编译defun定义上的任何使用该常数函数,我得到的错误消息:

  

没有MAKE-LOAD-FORM方法被定义   对于#S(POINT:X 0                                                    :Y 0                                                    位:Z 200)[式的条件   SIMPLE-ERROR]

我发现一个帖子说明并发症和另一个的感叹,但什么需要被添加到代码谈判OpenMCL的这个方面?

有帮助吗?

解决方案

当在代码作为文字,常量对象由编译正在处理的文件结构的对象(和其他一些类型的对象)出现,编译FILE需要知道如何安排,当所得到的二进制文件被加载,一个创建“等效”对象。还有的“等价”许多可能的定义:有时,但重要的是与其他对象加载的对象股权结构的组成部分,有时是很重要的初始化发生在一定的方式,有时没有这些东西都是非常重要的。要确定如何重新定对象,编译文件调用通用函数MAKE-LOAD-FORM;此行为应该任何CL参考或教程进行说明。 (参考或教程还应该注意,实现不能定义默认MAKE-LOAD-FORM方法将适用于结构CLASS或标准类的所有实例,并且还应该注意到,MAKE-LOAD-FORM-SAVING -SLOTS是MAKE-LOAD-FORM方法的对象,其初始化以使用并不需要很复杂,一个方便的功能,例如:

(defmethod make-load-form ((p point) &optional env)
  (declare (ignore env))
  (make-load-form-saving-slots p))

请注意该方法具有在编译时被定义,从而使COMPILE-FILE可以调用它来确定如何保存恒定点对象。

这一切都不是CCL-特定。什么可能是个问题,其中东西是常量,文字对象和东西都没有。

在类似的代码:

(defconstant a-point (make-point :x 0 :y 0 :z 200))

(defun return-a-point () a-point)

编译器的允许的(但不是必需的)来代替A-POINT的值在函数RETURN-A-POINT的引用。 (如果编译器这样做,那会 意味着有一个在代码中的字面/恒压点对象被编译,编译文件将需要调用MAKE-LOAD-FORM确定对象应如何保存和载入;如果编译器不执行此取代,然后MAKE-LOAD-FORM不需要在此示例中被调用。)

是否实现不执行这种替代或不可达的执行情况。该规范还留下它未具体说明以在DEFCONSTANT形式的值的形式是否是在编译时间,负载时间,或两者进行评价,并指出,必须小心(由用户),以确保表达始终计算为相同的值。

CCL通常尝试计算在编译时的DEFCONSTANT值形式,并且是相当积极约代替对它们的引用名为常数的值;在某些情况下,这意味着在常量值的类MAKE-LOAD-FORM方法必须被定义。其他的实现可能不太愿意为某些类型的对象做这个替代。这两种策略是正确的,可移植代码不能假设被遵循哪些策略(虽然多据称可移植代码可靠地并作出这样的假设。)

不同治疗由DEFCONSTANT定义的东西看起来像这样的事情(意外电话拨打-LOAD-FORM没有人想到要定义一个)的最可能原因。一个能避免一些问题的方式,应该是做便携式:

(defconstant a-point (make-point :x 0 :y 0 :z 200))

(defun return-a-point () (load-time-value (symbol-value 'a-point)))

这将产生类似的效果,以简单地允许想要这样做(如CCL确实)做恒定取代的实现,但使用LOAD-TIME-VALUE的将确保恒定值只在负荷评价时间(以及MAKE-LOAD-FORM不会涉及。)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top