[Openmcl-devel] Error with ccl:rlet
gb at clozure.com
Sun Nov 20 22:22:02 PST 2011
Section 13.1.2 of the manual doesn't make it at all clear, but the single
(supported) dimension of a foreign array type has to be specified as
(:array :address 3) ;legal syntax but not very general
(:array :address n) ;more useful but not supported.
If you're actually just interested in using RLET to create a 3-element array
of :ADDRESSes, you can do so:
(rlet ((my-array (:array :address 3)))
? (macroexpand-1 '(rlet ((my-array (:array :address 3)))))
(%STACK-BLOCK ((MY-ARRAY 24))
The stuff I left out of the macroepansion just has to do with "annotating" the
type of the foreign pointer. The constant 24 is just the constant 3 times the
size of an :ADDRESS (8 bytes on a 64-bit machine.) That arithmetic happened
at macroexpand time.
If we had foreign array types of non-constant size, then RLET would expand into
(%stack-block ((my-array (* <some-way-of-expressing-that-size> <size-of-array-elements>))) ...)
which means that we might do a little bit of arithmetic at runtime. The tricky
part of that is expressing it in terms of the foreign type system:
(rlet ((my-array (instantiate-parameterized-foreign-type (:array :address *) N)))
or some more digestable syntax. We'd like that to macroexpand into:
(%stack-block ((my-array (* n 8))) ...)
The moral of the story is that since (what I'm calling) parameterized foreign
array types don't exist, you can't get use them in RLET and have to use
%STACK-BLOCK yourself. (That's ultimately all that you're getting out of
RLET, but RLET is possibly more readable.)
Even if we don't want to try to introduce parameterized foreign types, there
are probably other ways of offering syntactic sugar, either as part of RLET
or by introducing new constructs. Something like:
(with-foreign-array ((my-array :address n))
might be more readable than the %STACK-BLOCK form it expands into, and
(with-foreign-array ((my-array (:struct :foo) n)) ...
would deal with questions of how big a (:STRUCT :FOO) is and how it needs
to be aligned in memory for you.
We don't have any of that, so you pretty much have to grimace and use
%STACK-BLOCK for cases like this.
On Sun, 20 Nov 2011, idan mandelbaum wrote:
> I am trying to do the following:
> (let ((x 3))? (ccl:rlet ((my-array (:array :address x)))))
> basically use a variable for the array length. I get the following error:
> First dimension is not a non-negative fixnum or NIL: X
> ?? [Condition of type SIMPLE-ERROR]
> I tried to force x to be fixnum:
> (let ((x 3))? (declare (fixnum x)) (ccl:rlet ((my-array (:array :address x)))))
> I still get the same error. What am i doing wrong?
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
More information about the Openmcl-devel