常见的lisp:值16777216不是预期的类型(UNSIGNED-BYTE 24)

时间:2013-08-21 08:29:45

标签: arrays common-lisp ccl

我在Windows 7上使用Clozure-CL。我为测试编写了一个简单的“图像”类(好吧,结构)。

(defmacro -> (struct slot) `(slot-value ,struct ,slot))

(defstruct 
  (image 
    (:constructor make-image (&key width height (bytes-per-pixel 4) 
        (pixels (make-array (* bytes-per-pixel (* width height))
                                :element-type '(unsigned-byte 8)))))
    (:print-function (lambda (img s k)
                       (declare (ignore k)) 
               (format s "image(~ax~a@~abpp)"
                               (-> img 'width) (-> img 'height)
                               (* 8 (-> img 'bytes-per-pixel))))))
  (width 0 :type '(unsigned-byte 32))
  (height 0 :type '(unsigned-byte 32))
  (bytes-per-pixel 4 :type '(unsigned-byte 32))
  (pixels nil))

不幸的是,当我尝试这样做时:

(make-image :width 2048 :height 2048)

我收到此错误:

value 16777216 is not of the expected type (UNSIGNED-BYTE 24).
   [Condition of type TYPE-ERROR]

这是堆栈跟踪(从slimv复制粘贴):

  0: (CCL::MAKE-UARRAY-1 207 16777216 NIL NIL NIL NIL NIL NIL NIL 16777216)
  1: (MAKE-IMAGE :WIDTH 2048 :HEIGHT 2048 :BYTES-PER-PIXEL 4 :PIXELS 16777216)
  2: (CCL::CALL-CHECK-REGS MAKE-IMAGE :WIDTH 2048 :HEIGHT 2048)
  3: (CCL::CHEAP-EVAL (MAKE-IMAGE :WIDTH 2048 :HEIGHT 2048))
  4: (SWANK::EVAL-REGION "(make-image :width 2048 :height 2048)\n")
  5: ((:INTERNAL SWANK::REPL-EVAL))
  6: (SWANK::TRACK-PACKAGE #<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::REPL-EVAL) #x19D56EAE>)
  7: (SWANK::CALL-WITH-RETRY-RESTART "Retry SLIME REPL evaluation request." #<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::REPL-EVAL) #x19D56EFE>)
  8: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::REPL-EVAL) #x19D56F26>)
  9: (SWANK::REPL-EVAL "(make-image :width 2048 :height 2048)\n")
 10: (CCL::CALL-CHECK-REGS SWANK:LISTENER-EVAL "(make-image :width 2048 :height 2048)\n")
 11: (CCL::CHEAP-EVAL (SWANK:LISTENER-EVAL "(make-image :width 2048 :height 2048)\n"))
 12: (SWANK:EVAL-FOR-EMACS (SWANK:LISTENER-EVAL "(make-image :width 2048 :height 2048)\n") "GAME" 135)
 13: (SWANK::PROCESS-REQUESTS NIL)
 14: ((:INTERNAL SWANK::HANDLE-REQUESTS))
 15: ((:INTERNAL SWANK::HANDLE-REQUESTS))
 16: (SWANK-BACKEND:CALL-WITH-DEBUGGER-HOOK #<Compiled-function SWANK:SWANK-DEBUGGER-HOOK #x186F1EF6> #<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::HANDLE-REQUESTS) #x1882D666>)
 17: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-OUTPUT* . #<SWANK-BACKEND::SLIME-OUTPUT-STREAM #x188247CE>) (*STANDARD-INPUT* . #<SWANK-BACKEND::SLIME-INPUT-STREAM #x188249DE>) ..))) #<CCL:COMPILED-LEXICAL-CLO..
 18: (SWANK::HANDLE-REQUESTS #<MULTITHREADED-CONNECTION  #x1880CB0E> NIL)
 19: (CCL::RUN-PROCESS-INITIAL-FORM #<PROCESS repl-thread(12) [Active] #x18824C8E> (#<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL CCL::%PROCESS-RUN-FUNCTION) #x18824B46>))

据我了解,Clozure-CL使用一些内部函数来生成字节数组,并且由于某种原因,这个函数需要24位整数参数用于数组大小,并且因为16777216是2 24 ,所以不适合24位整数。我想删除这个限制。我该如何解决这个问题?

修改

我检查了文档并发现在32位Clozure-CL上,最大数组大小限制(array-total-size-limit)是(expt 2 24)。 64位版本有一个更大的限制,但我仍然可以做些什么吗?

1 个答案:

答案 0 :(得分:2)

正如您已经发现的那样,这是32位Clozure CL版本的限制。 64位Clozure CL版本有更大的限制。

在我的Mac上:

? array-total-size-limit
72057594037927936

你能做什么:

  • 使用几个较小的数组并将其隐藏在某个界面后面。痛苦。
  • 使用FFI在C端分配数组。有点痛苦。确保你有一些类型/边界检查,并使内存管理正确。
  • 使用64位版本。也许这是你的选择?

如果有的话,32位版本的实施限制不容易改变。