[plt-scheme] Bug report / request for comment concerning foreign.ss
(module ffi-bug mzscheme
(require (lib "foreign.ss" )) ;; (unsafe!)
;;
;; BUG / FEATURE
;;
;; When declaring a c structure using define-cstruct
;; ctype-sizeof reports more bytes than was asked for
;; in the declaration.
;;
;; This bug is illustrated by the code and results below.
;;
;; The response I expect to this bug report is that it is in fact
;; a feature as opposed to a bug.
;;
;; To save an iteration on the Q & A loop.
;; I'm going to anticipate that response and reply to it:
;;
;; Whether or not a structure is implicitly padded may not be in the
;; control of the programmer developing the scheme interface to a C
;; library. Some structures will be padded others won't be so the
;; marshalling infrastructure has to expose control of padding and
;; alignment to the programmer defining an interface.
;;
;; In my opinion it is generally a mistake to hide such
;; behaviour because the programmer needs to be thinking about
;; the issue. Hiding it leads to mistakes.
;; It is desirable to leave the padding/alignment issue in the open.
;;
;; To be clear, individual interfaces can vary on the same O.S. on
;; the same hardware. C compiler features permit individual structures
;; to be padded or not as and when required.
;;
;; See MSVC #pragma Pack.
;;
;; See Gnu C compiler: __attribute__((__packed__))
;;
;; (discussed here : http://www.grok2.com/structure_packing.html )
;;
;; In fact it is quite possible to have a situation where an outer
;; structure is padded, and an inner field member structure is not,
;; or vice versa. Granted, that is a C programmer looking for trouble.
;;
;; Code to illustrate the issue below:
;;
;; This test ran as is, producing the results shown below as comments
;; I'm hoping it won't get munged by email sw along the
;; the way, and anyone can just cut it and run it in Drscheme.
;;
(define _bugtest2 (make-cstruct-type (list _int32 _int32)))
(display "Expect 8:")
(display (format "_bugtest2 size: ~a" (ctype-sizeof _bugtest2)))
(newline)
(define _bugtest3 (make-cstruct-type (list _int32 _int32 _int32)))
(display "Expect 12:")
(display (format "_bugtest3 size: ~a" (ctype-sizeof _bugtest3)))
(newline)
(define _bugtest4 (make-cstruct-type (list _int32 _int32 _int32 _int32)))
(display "Expect 16:")
(display (format "_bugtest4 size: ~a" (ctype-sizeof _bugtest4)))
(newline)
(define-cstruct _define-struct-test1 ((field1 _int32)
(field2 _int32)
(field3 _int64)))
(display "Expect 16:")
(display (format "_define-struct-test1 size: ~a" (ctype-sizeof
_define-struct-test1)))
(newline)
(define-cstruct _define-struct-test2 ((field1 _int32)
(field2 _int32)
(field3 _int64)
(field_sub1 _bugtest2)))
(display "Expect 24:")
(display (format "_define-struct-test2 size: ~a" (ctype-sizeof
_define-struct-test2)))
(newline)
(define-cstruct _define-struct-test3 ((field1 _int32)
(field2 _int32)
(field3 _int64)
(field_sub1 _bugtest3)))
(display "Expect 28:")
(display (format "_define-struct-test3 size: ~a" (ctype-sizeof
_define-struct-test3)))
(newline)
(define-cstruct _define-struct-test4 ((field1 _int32)
(field2 _int32)
(field3 _int64)
(field_sub1 _bugtest4)))
(display "Expect 32:")
(display (format "_define-struct-test4 size: ~a" (ctype-sizeof
_define-struct-test4)))
(newline)
(define-cstruct _define-comp-struct1 ((field_sub1 _define-struct-test3)
(field_sub2 _define-struct-test3)))
(display "Expect 56:")
(display (format "_define-comp-struct1 size: ~a" (ctype-sizeof
_define-comp-struct1)))
(newline)
)
;;;
;;; results
;;;
;Expect 8:_bugtest2 size: 8
;Expect 12:_bugtest3 size: 12
;Expect 16:_bugtest4 size: 16
;Expect 16:_define-struct-test1 size: 16
;Expect 24:_define-struct-test2 size: 24
;Expect 28:_define-struct-test3 size: 32 <===== 4 byte discrepancy.
;Expect 32:_define-struct-test4 size: 32
;Expect 56:_define-comp-struct1 size: 64 <===== propagated now 8 byte
discrepancy.
;;;
;;; Test environment information
;;;
; context -> mzscheme version 372
; context -> time of test is 2008-11-04 09:33:17
; context -> O.S. windows
; context -> Machine Windows NT 5.0 (Build 2195) Service Pack 4
; context -> Garbage Collector (gcc or 3m) 3m
; context -> Link dll
; context -> Shared Object suffix .dll
; context -> language/country English_Canada