A while ago, somebody pointed out that structures with array members don't
compile properly on Verrazano.
In looking at the issue, I realized that arrays are something of a special
case in C-FFI, as they are morally
type-specifiers in defcstruct declarations, but do not have underlying
types. Therefore, I propose a new C-FFI
declaration:
(defcarray <foreign-type-name> <base-type> <length>)
eg:
int[5] -> (defcarray int-array :int 5)
An explicit nil for the <length> argument would be equivalent to:
(define-foreign-type int-array () ':pointer)
All array types would be passed as :pointer under the hood, just like
structure types.
Philosophically, it might be undesirable to add array types in order to keep
with the minimally-typed design
of C-FFI. However, arrays, from the point of view of C semantics, are much
more similar to structures than
to pointers. Indeed, in the C machine model, a structure is little more than
a hetrogenous array. Thus, the
treatment of arrays versus structures in the C-FFI API presents something of
an inconsistency, as:
(defcstruct foo (a1 :int) (a2 :int))
(define-foreign-type bar () 'foo)
(defcstruct baz (q bar))
is perfectly legal code, while:
(defcarray foo :int 2)
(define-foreign-type bar () 'foo)
(defcstruct baz (q bar))
is unrepresentable.
This issue makes C-FFI somewhat incongruous with C, because in C, a
structure field as a name and a type,
with array's being incorporated into the type system, while in C-FFI, a
structure field has a name, a type,
and an optional length, with no explicit array type. Moreover, since arrays
are not types, the usual type
machinery that can be used on array types in C header files must be
translated into other things in C-FFI
declaration files.
Now, there is a somewhat selfish undertone to this proposal, as the lack of
array types in C-FFI necessitates
a rather ugly special case in Verrazano's C-FFI backend. However, I believe
that an array type would be
an improvement for hand-made C-FFI declarations as well, specifically for
cases where an array type
is not specified directly in a structure, but used via typedef in a
structure.
Sincerely,
Rayiner Hashem