[Openmcl-devel] def-foreign-type problem

Gary Byers gb at clozure.com
Sat Sep 21 22:46:09 PDT 2002

On Sat, 21 Sep 2002, John DeSoi wrote:

> If I define a struct with a short followed by a long, the allocation
> size given is 8 bytes instead of 6. This is a big problem for
> accessing any fields after the long value. Am I using this
> incorrectly?
> Thanks,
> John DeSoi, Ph.D.
> =====
> (ccl::def-foreign-type nil
> 		       (:struct tst
> 			(:f1 :short)
> 			(:f2 :long)))
> ? (ccl::%foreign-type-or-record-size :tst :bytes)
> 8

That's as expected (and is equivalent to what you'd get if you compiled:

struct {
  short f1;
  long f2;

in C (under default alignment rules.)  It's also equivalent to:

(ccl::def-foreign-type nil
                  (:struct tst-with-explicit-padding
                     (:f1 :short)
                     (:pad :short) ; ensure 32-bit alignment of the following
                     (:f2 :long)))

On most CPUs (including the PPC), it's substantially more efficient to
load/store scalar objects from/to memory if the object's alignment is
a multiple of its size.  On some CPUs (including the PPC in some cases),
a misaligned memory reference can cause a hardware exception; a software
handler might then have to emulate the load or store, a byte at a time.
(In some cases, this behavior can be exploited by a lisp implementation
to get some kinds of type-checking "for free", but I digress ...)

These sorts of alignment considerations weren't a factor for the MC68000
CPUs used in the original Macintosh (18 years ago); that was sort of a
hybrid 16/32-bit system that only cared that something that was at least
16 bits wide was aligned on a 16-bit boundary.  Later 68K-series CPUs
-did- care about "natural alignment", but by then it was too late: legacy
MacOS data structures (those introduced before the 68020 became prevalent,
basically) are defined with the original 16-bit alignment rules in effect,
and Apple's chosen to maintain binary compatibility all these years.

PPC C compilers for MacOS systems generally have to be taught to observe:

#pragma options align=mac68k


#pragma options align=reset

and have to align structure elements to 16-bit boundaries when the
"mac68k" alignment option is in effect.

Over its last few iterations, OpenMCL's interface translator has
improved its ability to deal with 16-bit alignment in legacy MacOS
data structures; unfortunately, it works at a slightly lower level

I suppose that if 16-bit alignment has stuck around for 15 or 16
years after it stopped making sense, it probably isn't going away
soon.  Perhaps that means that DEF-FOREIGN-TYPE should support
some way of defining structs/unions with non-default alignment.

(Whether this happens or not, OpenMCL's foreign type system should
really be made to understand vector (AltiVec/VMX/"Velocity Engine")
alignment restrictions. Those restrictions affect semantics
as well as performance, as anyone who saw funny-colored text and
menu titles when running early versions of the Cocoa demo on some
G4s can attest.)

Out of curiosity, did you ask about this because you have some C code
that assumes 16-bit alignment, or were you just curious ?  (I'd sort
of convinced myself that there was no need to handle 16-bit alignment
in DEF-FOREIGN-TYPE, since that would only exist in a few old Apple
header files that the interface translator should process ...)

> ; Warning: Redefining STRUCT TST to be:
> 16)) (:F2 (CCL::SIGNED 16))) #x530BB6E>,
> ;          was:
> 16)) (:F2 (CCL::SIGNED 32))) #x530B6AE>
> (ccl::def-foreign-type nil
> 		       (:struct tst
> 			(:f1 :short)
> 			(:f2 :short)))
> ? (ccl::%foreign-type-or-record-size :tst :bytes)
> 4
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/cgi-bin/mailman/listinfo/openmcl-devel

Openmcl-devel mailing list
Openmcl-devel at clozure.com

More information about the Openmcl-devel mailing list