From: Vincent A. <vi...@ar...> - 2005-01-08 13:55:33
|
Hi, Have a look at these nearly identical ways to calculate (decode-universal-time (get-universal-time)): $ bin/uninstalled-sbcl This is SBCL 0.8.18.18, an implementation of ANSI Common Lisp. More information about SBCL is available at <http://www.sbcl.org/>. SBCL is free software, provided as is, with absolutely no warranty. It is mostly in the public domain; some portions are provided under BSD-style licenses. See the CREDITS and COPYING files in the distribution for more information. * (machine-type) "X86-64" * (decode-universal-time (get-universal-time)) 10 44 23 7 1 2005 4 T 0 * (get-universal-time) 3314126650 * (decode-universal-time *) 10 44 23 7 1 2005 4 NIL -1 * Note that the last two values of each call to decode-universal-time are different. (The last result is the correct one.) I'm still somewhat mystified by the two result being different, but I do think I understand what causes the wrong answer: a type mismatch. src/runtime/time.c: void get_timezone(time_t when, int *secwest, boolean *dst) ^^^^^^^ src/runtime/runtime.h: /* Too bad ANSI C doesn't define "bool" as C++ does.. */ typedef int boolean; ^^^ src/code/unix.lisp: (define-alien-routine get-timezone sb!alien:void (when sb!alien:long :in) (seconds-west sb!alien:int :out) (daylight-savings-p sb!alien:boolean :out)) ^^^^^^^ src/code/host-alieneval.lisp: (define-alien-type-translator boolean (&optional (bits sb!vm:n-word-bits)) ^^^^^^^^^^^ (make-alien-boolean-type :bits bits :signed nil)) And indeed, changing the sb!alien:boolean declaration in get-timezone into (sb!alien:boolean 32) seems to fix this. I'm not sure whether that's the right place to fix it, though. I wouldn't expect any C programmer to use a long to hold a boolean. An int would be more likely, so in that light it would be more practical to change the default size of a boolean in the above definition from n-word-bits into either 32 or (sb!alien:alien-size sb!alien:int). On the other hand, from some random internet pages I understand that C99 has a _Bool type (and stdbool.h defines bool to be _Bool, false to be (_Bool)0 and true to be (_Bool)1). I assume its size is not in the C99 standard, but gcc 3.2 on x86 and gcc 3.3.5 on x86-64 both tell me that sizeof(bool) is sizeof(_Bool) is 1. (To make this a bit more fun, gcc 2.95.4 also comes with a stdbool.h, but this one defines bool as en enumeration type, so sizeof(bool) is 4.) I still think however that the option of least surprise when dealing with most current C code is to make sb-alien:boolean default to 32 bits, so my vote would be for that one. Vincent. |