summary: strangeness with classes defined from C reported: Andreas Rottmann , 2002-04-17 As my C++ <-> Guile bindings (ucxx.sf.net) are approaching completeness, I have run into another strange problem. I have managed to isolate the code that causes it and wrote a self-contained C program that exposes the bug. Here is what I do: 1) I create a new class, containing one slot using scm_basic_create_class(). 2) I then add a method to 'initialize', specialized for the newly created class, that calls a C function. 3) I create a new class, inheriting from the C-created class, and instantiate one object of the new class (using make). 4) I do (define-method (initialize (obj ) initargs) (next-method)). This expression leads to this: ERROR: In procedure struct-ref: ERROR: Wrong type argument in position 1 (expecting STRUCTP): () A backtrace (using my original code) is attached, but you should easily be able to reproduce and investigate this strange behaviour using the attached C program. I hope someone can shed light on this strange thing... Regards, Andy [2. text/x-csrc; bug.c] #include #include static SCM my_constructor(SCM obj, SCM initargs) { printf("constructor called!\n"); scm_slot_set_x(obj, scm_str2symbol("a-slot"), SCM_BOOL_T); return obj; } static void set_constructor(SCM klass, SCM (*proc)(SCM, SCM)) { SCM initialize = scm_variable_ref( scm_c_module_lookup(scm_module_goops, "initialize")); SCM sym_obj = scm_str2symbol("obj"); SCM sym_args = scm_str2symbol("args"); SCM constr = scm_c_make_gsubr("constructor", 1, 0, 1, proc); SCM constrm = scm_closure(scm_list_2(scm_list_2(sym_obj, sym_args), scm_list_3(constr, sym_obj, sym_args)), SCM_EOL); SCM meth = scm_make(scm_list_5(scm_class_method, scm_c_make_keyword("specializers"), scm_list_2(klass, scm_class_top), scm_c_make_keyword("procedure"), constrm)); scm_add_method(initialize, meth); } static void real_main(void *closure, int argc, char *argv[]) { SCM klass, slots; scm_load_goops(); slots = scm_list_1(scm_list_3(scm_str2symbol("a-slot"), scm_c_make_keyword("init-value"), SCM_BOOL_F)); klass = scm_basic_make_class(scm_class_class, scm_makfrom0str(""), scm_list_1(scm_class_object), slots); set_constructor(klass, my_constructor); scm_c_define("", klass); scm_c_eval_string("(use-modules (oop goops))"); scm_c_eval_string("(define-class ())"); scm_c_eval_string("(make )"); // this produces the error scm_c_eval_string("(define-method (initialize (obj ) initargs)" " (next-method))"); } int main(int argc, char *argv[]) { scm_boot_guile(argc, argv, real_main, NULL); return 0; } Backtrace: In unknown file: ?: 0* [primitive-load "bug.scm"] In bug.scm: 7: 1* (define-method (initialize (obj ) initargs) (next-method)) 7: 2 (begin (if # #) (add-method! initialize #)) In unknown file: ?: 3 [add-method! #< initialize (13)> ... ?: 4* (method ((obj ) initargs) (next-method)) ?: 5 [make-instance # 80844c0> #:specializers ...] In /usr/local/share/guile/1.7.0/oop/goops.scm: 1420: 6 (let ((instance #)) (initialize instance initargs) instance) 1421: 7* [initialize #< 8086a90> (#:specializers (# #) #:procedure ...)] In unknown file: ?: 8* [memoize-method! #< initialize (13)> (# #) ...] In /usr/local/share/guile/1.7.0/oop/goops/dispatch.scm: 241: 9* (let ((applicable #)) (cond (applicable #) (# #) (else # # #))) 245: 10 (cond (applicable #) (# #) (else # # #)) 251: 11 (let* ((new #) (res #)) (set-cdr! (cdr exp) (cddr new)) res) 253: 12* (cond (# #) (# #) (else #)) 257: 13 [method-cache-install! # # # ...] ... 289: 14 (let* ((types #) (entry+cmethod #)) (insert! exp (car entry+cmethod)) ...) 291: 15* [hashed-method-cache-insert! (#@dispatch args 2 0 ...) (# # # # ...)] 169: 16 (let* ((cache #) (size #)) (let* (# # # ...) (do # # ...) ...)) 171: 17 (let* ((entries #) (size #) (min-misses size) ...) (do (#) (#) ...) ...) 180: 18* (do ((hashset 0 (+ 1 hashset))) ((= hashset hashsets)) ...) 182: 19* (let* ((test-cache #) (misses #)) (cond (# # # # ...) (# # # #))) 183: 20* [cache-try-hash! 4 0 ...] 210: 21 (let ((max-misses 0) (mask #)) (catch (quote misses) (lambda () #) ...)) 212: 22 [catch misses # #] In unknown file: ?: 23* [#] In /usr/local/share/guile/1.7.0/oop/goops/dispatch.scm: 214: 24* (do ((ls entries (cdr ls)) (misses 0 0)) ((null? ls) max-misses) ...) 217: 25* (do ((i # #)) ((not #) (vector-set! cache i ...)) ...) 217: 26* [logand 3 ... 217: 27* [cache-hashval 0 (# # () # ...)] 203: 28 (let ((hashset-index #)) (do (# #) (# sum) (set! sum #))) 204: 29 (do ((sum 0) (classes entry #)) ((environment? #) sum) ...) 207: 30* (set! sum (+ sum (struct-ref (car classes) hashset-index))) 207: 31* [+ 4312081437 ... 207: 32* [struct-ref () 6] /usr/local/share/guile/1.7.0/oop/goops/dispatch.scm:207:24: In procedure struct-ref in expression (struct-ref (car classes) hashset-index): /usr/local/share/guile/1.7.0/oop/goops/dispatch.scm:207:24: Wrong type argument in position 1 (expecting STRUCTP): ()