[Haskell-cafe] c2hs, size_t, and CSize -- argh!

Duncan Coutts duncan.coutts at googlemail.com
Thu Oct 1 12:37:12 EDT 2009

On Thu, 2009-10-01 at 10:20 -0400, John Van Enk wrote:
> Hello List,
> I'm running into a problem with c2hs and how it parses the C typedef
> 'size_t'. On 32bit systems, this ends up being parsed as a CUInt. On
> 64bit systems, this ends up as a CULong. This gets especially sticky
> with function pointers.

Right. Of course that's because on those different platforms size_t
really is a typedef for unsigned int or unsigned long.

> I see there is a ticket open for this:
> http://hackage.haskell.org/trac/c2hs/ticket/20
> Has any one else run into this issue? Is there a good workaround that
> doesn't involve writing a C function/typedef for each collision?

So what you would want, presumably, is to map the "size_t" typedef to
the Haskell type Foreign.C.Types.CSize, rather than what c2hs discovers
as the actual raw type of "size_t". Then you're making the promise that
unsigned long, or unsigned int really really does match

Currently c2hs has no support for remapping basic types like that.

As for a workaround, just use fromIntegral to convert to CSize. You know
this is always possible because you know CSize matches CUInt or CULong
on the appropriate platforms.

$ cat foo.h
#include <stddef.h>
size_t foo(void);

$ cat foo.c
#include "foo.h"
size_t foo(void) { return 42; }

$ cat foo.chs

import Foreign.C.Types
foo :: IO CSize
foo = fmap fromIntegral {# call foo as bar #}

$ gcc -c foo.c
$ c2hs foo.h foo.chs
$ ghci foo.hs -fffi foo.o
Main> foo


More information about the Haskell-Cafe mailing list