[plt-scheme] Bug report / request for comment concerning foreign.ss

From: Ernie Smith (esmith at acanac.net)
Date: Tue Nov 4 10:31:24 EST 2008

(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



Posted on the users mailing list.