6

Common Lisp の少なくとも一部の実装では、ユーザー定義の定数を一部の型指定子で配列の次元として使用することを許可していません。たとえば、SBCL では、このコードは次のようになります。

(defconstant +len+ 3)

(defun foo (x) 
  (declare (type (simple-array fixnum (+len+)) x))
  x)

次のエラーが生成されます。

; in: DEFUN FOO
;     (TYPE (SIMPLE-ARRAY FIXNUM (+LEN+)) X)
; 
; caught ERROR:
;   bad dimension in array type: +LEN+

なんで?ある種のグローバル定義を使用して複数の型指定子を調整できることが望ましいため、ユーザー定義の定数を型指定子で使用できないことは驚くべきことです。型指定子はコンパイル時に完全に理解できる必要があることを理解しています。defconstantしかし、コンパイラーは、定義されたシンボルをリテラル値で置き換えることができると思っていました。これが の目的の 1 つであると私は考えたでしょうdefconstant。(これまでのところ、Common Lisp Hyperspec、CLTL2、SBCL マニュアル、または Google が発見したものから、この問題をより深く理解することに成功していません。何らかの形で答えがあると思います ....)

4

5 に答える 5

3

他の2つの回答は、制限を回避する方法と、標準で制限が指定されている場所を示しています

この制限がどこから来ているのかをお話しします。

その理由は、Lisp 宣言は、人間が読むためのコード ドキュメントとしてだけでなく、コンパイラがコードを最適化する際の助けとしても意図されているためです。つまり、宣言された配列サイズは、コンパイラが必要に応じて固定サイズの配列を割り当て、配列インデックスのストレージ要件を推測できるようにする必要があります。Cのようなコードを禁止する制限に似ています。

int N = 10;
int v[N];

コンパイラの POV から宣言を見始めると、要件は非常に自然になります。

于 2013-09-30T13:23:36.347 に答える