[racket-dev] cstruct and properties

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Thu Nov 8 08:55:21 EST 2012

At Wed, 7 Nov 2012 20:00:51 +0100, Tobias Hammer wrote:
> i am currently playing around with properties attached to cstructs and ran  
> into some problems.
> 
> Normally, with racket structs, i can access a property without an instance  
> of the struct via the struct type descriptor (struct:S). There seems to be  
> nothing similar for cstructs, so the only way i found to check for or  
> access a property is to create a dummy instance solely for this purpose.
> Would it be possible to add a similar type descriptor for cstructs? To  
> account for the incompatibility with the one for structs it might make  
> sense to name it different, maybe cstruct:S or similar.
>
> If such a descriptor would exists it should be included in the transformer  
> bindings for cstructs.

Yes, that makes sense.

> Another info i am really missing there is the  
> super-type field. As far as i can see, it would be a valid semantic to set  
> it to the identifier if the cstruct was created by type and to set it #f  
> if it got its super-type by cpointer.

Right.

> But one more thing on properties. A source of really nasty bugs is if you  
> try to use the ctype of a cstruct inside the property:
> 
> (define-values (p p? p-ref) (make-struct-type-property 'my-p))
> (define-cstruct _S ([a (_array _byte 23)])
>    #:property p _S)
> (define s (ptr-ref (malloc _S) _S)) ; dummy instance
> 
> Getting the value results in:
> (p-ref s)
> > #<ctype>
> (ctype-sizeof (p-ref s))
> > 4
> 
> Checking ffi/unsafe.rkt shows that i get a temporary cpointer as ctype.  
> The real type already exists at the time the wrapper-struct is created but  
> it is not yet accessible by the name _S.
> The following small patch should solve this by locally introducing the  
> correct name during the struct creation.

It's interesting that you can make that work in the current
implementation, but I worry about guaranteeing that order for the
future. I'm inclined instead to say that the above declaration should
have signaled an error due to an too-early use of `_S', just like

  (struct a () #:property prop:procedure struct:a)

The repair to `define-cstruct', then, would be to lift the property and
property-value expressions out of the nested scope where they currently
are evaluated.

Is it important for your purposes that the `define-cstruct' declaration
above works? Or could you use a thunk to delay reference, as in

 (define-cstruct _S ([a (_array _byte 23)])
    #:property p (lambda () _S))

?

Posted on the dev mailing list.