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