Food for thought here. Simon
| -----Original Message----- | From: haskell-cafe-boun...@haskell.org [mailto:haskell-cafe- | boun...@haskell.org] On Behalf Of Evan Laforge | Sent: 01 January 2013 23:18 | To: haskell | Subject: [Haskell-cafe] hsc2hs and Storable (especially) unsafe | | It so happens that on 64 bit OS X, haskell's Int is 64 bits, while C's | int is | 32 bits. hsc2hs's #poke does no typechecking at all, so if you have | | (#poke Struct, int_field) structp int -- where int :: Int | | Then you probably are going to corrupt memory, and in a particularly | pernicious way (since chances are it won't segfault). Similarly, don't | poke haskell Chars, it has to be CChar. And what's even worse, | Foreign.withArrayLen gives you an Int, not a CInt! So doing the obvious | thing and poking the pointer and length directly is wrong. And besides, | shouldn't it be a CSize? Another trap: C++'s bool is probably one byte, | haskell's Bool Storable says it's 4. It's probably not even correct to | assume Double = CDouble and Float = CFloat, though it seems likely to be | always true. | | I carefully vetted all my #pokes but I'm annoyed that hsc2hs and Foreign | let me get away with this. If Storable is for marshalling types to and | from C, then non-C types should not be Storable! If Storable is useful | for other things (and it is!), then Foreign should define its own | CStorable, that only includes C types, and hsc2hs should use that! | | While we're at it, fromIntegral is not a safe way to convert a haskell | type to a C one. But it sure is a tempting one, because Foreign.C | doesn't provide any conversion functions (except for Bool). We should | have explicit conversion functions that give the choice of crashing with | an error or clamping the number to the (smaller) C type's bounds. I'm | not sure if anyone wants what fromIntegral does. | | Or maybe I shouldn't be using hsc2hs in the first place. I feel more | and more that it gives haskell a bad name, being low level and error | prone. I used bindings-dsl for a libgit2 binding, and at least it | automates Storable instances, so it's less error-prone that way. I'd | like to generate instances directly from .h files though, so I should | probably check out c2hs. | | Back in the day when I was deciding to use hsc2hs I noticed how it lacks | typechecking, but I thought that it's just a few fields, I can be | careful when writing them. But one of the lessons from haskell (and | static analysis in | general) is that "just be careful" is going to fail you some day, | probably sooner than you think. | | So anyway, I wrote a ForeignC module that defines CStorable that only | includes C types. At first I thought I could make Storable a superclass | and just re-export functions with more restritive signatures, but then | it gets tricky because you wind up needing the Storable peek and poke to | declare Storable instances. So I defined a completely new CStorable, | and all you need to do is import ForeignC instead of Foreign, and change | 'instance Storable ...' to 'instance CStorable ...'. Unfortunately that | apparently means copy-pasting over the Storable-using utilities like | 'with' and 'newArray'. | | On the plus side, I dropped it into my .hsc modules, and it found | several | *more* mistakes. | | I was thinking of putting it on hackage (along with the conversion | functions), since other people might have made these same mistakes, but | it's unpleasant because it duplicates so much from Foreign. Also, I | only copied over the bits I'm using, so it's not complete either. Is | there a better way to create safe Storable instances for C? I'd be | happier with a solution that avoids the need to write Storable instances | in the first place, but hsc2hs is here now, and used in a lot of places. | | _______________________________________________ | Haskell-Cafe mailing list | haskell-c...@haskell.org | http://www.haskell.org/mailman/listinfo/haskell-cafe _______________________________________________ Cvs-ghc mailing list Cvs-ghc@haskell.org http://www.haskell.org/mailman/listinfo/cvs-ghc