{# sizeof #} hook going wrong for cases of structs with embeded arrays.

c2hs is calculating the sizeof glib's GValue structure incorrectly (this led to a nasty bug). GValue is defined like this: struct _GValue { /*< private >*/ GType g_type; /* public for GTypeValueTable methods */ union { gint v_int; guint v_uint; glong v_long; gulong v_ulong; gint64 v_int64; guint64 v_uint64; gfloat v_float; gdouble v_double; gpointer v_pointer; } data[2]; }; We used to use this code: allocaGValue :: (GValue -> IO b) -> IO b allocaGValue body = allocaBytes {# sizeof GValue #} $ \gvPtr -> do ... but we eventually discovered that {# sizeof GValue #} was giving us the wrong value, I think it was 8. The right value should be 8+8+4=20. Our current workaround is: allocaGValue :: (GValue -> IO b) -> IO b allocaGValue body = -- c2hs is broken in that it can't handle arrays of compound arrays in the -- sizeof hook allocaBytes ({# sizeof GType #}+ 2* {# sizeof guint64 #}) $ \gvPtr -> do Axel also added this temporary hack so that at least c2hs would report an error rather the giving the wrong answer: --- ../build/gtk2hs-0.9.10/tools/c2hs/c/CTrav.hs 2004-11-21 21:05:27.000000000 +0000 +++ ../build/gtk2hs/tools/c2hs/c/CTrav.hs 2006-04-25 18:53:10.000000000 +0100 @@ -73,7 +73,7 @@ -- isTypedef, simplifyDecl, declrFromDecl, declrNamed, declaredDeclr, declaredName, structMembers, expandDecl, - structName, enumName, tagName, isPtrDeclr, dropPtrDeclr, + structName, enumName, tagName, isArrDeclr, isPtrDeclr, dropPtrDeclr, isPtrDecl, isFunDeclr, structFromDecl, funResultAndArgs, chaseDecl, findAndChaseDecl, checkForAlias, checkForOneAliasName, lookupEnum, lookupStructUnion, @@ -537,6 +537,16 @@ isPtrDeclr (CFunDeclr declr _ _ _) = isPtrDeclr declr isPtrDeclr _ = False +-- checks whether the given declarator defines an object that is an array of +-- some other type (EXPORTED) +-- +-- * difference between arrays and pure pointers is important for size +-- calculations +-- +isArrDeclr :: CDeclr -> Bool +isArrDeclr (CArrDeclr declr _ _) = True +isArrDeclr _ = False + -- drops the first pointer level from the given declarator (EXPORTED) -- -- * the declarator must declare a pointer object --- ../build/gtk2hs-0.9.10/tools/c2hs/gen/GenBind.hs 2005-10-17 21:41:30.000000000 +0100 +++ ../build/gtk2hs/tools/c2hs/gen/GenBind.hs 2006-04-25 18:53:10.000000000 +0100 @@ -1665,6 +1667,8 @@ -- * we make use of the assertion that `extractCompType' can only return a -- `DefinedET' when the declaration is a pointer declaration -- +sizeAlignOf (CDecl specs [(Just declr, _, size)] ats) | isArrDeclr declr = + interr $ "sizeAlignOf: calculating size of constant array not supported." sizeAlignOf cdecl = do ct <- extractCompType cdecl So, that's the temporary solution. Of course it'd be better if we could actually calculate this struct size. This issue of struct sizes (and alignments) is probably an area that needs more testing (and on other arches since eg MS packs bit-fields differently). Perhaps we could write a prog that scans a header file and generates a .chs and .hsc file with {# sizeof #} hooks for every structure. Then we could compare the two (with various headers and on various platforms) and see where the remaining issues are. Using .hsc as a reference would be the right thing here because hsc2hs uses gcc to find the struct size. That same kind of test would also do for struct member offsets. Duncan

Duncan Coutts wrote: [something bad about arrays embedded in structures] I just got bitten by the same bug. C2HS doesn't even attempt to calculate the size of arrays inside structures, so not only sizeOf hooks go wrong, but get and set hooks, too. My first call into libdb accordingly ended somewhere in the wilderness. Attached is my attempt at a fix. I'm not sure this is the most elegant way to go about it, but some limited testing shows it working. BTW, this comment at GenBind.hs line 1662 is no longer valid, isn't it?
-- * we make use of the assertion that `extractCompType' can only return a -- `DefinedET' when the declaration is a pointer declaration
Regards, Udo.
Duncan
_______________________________________________ C2hs mailing list C2hs@haskell.org http://www.haskell.org/mailman/listinfo/c2hs
-- Worrying is like rocking in a rocking chair -- It gives you something to do, but it doesn't get you anywhere.

Udo Stenzel:
Duncan Coutts wrote: [something bad about arrays embedded in structures]
I just got bitten by the same bug. C2HS doesn't even attempt to calculate the size of arrays inside structures, so not only sizeOf hooks go wrong, but get and set hooks, too. My first call into libdb accordingly ended somewhere in the wilderness.
Attached is my attempt at a fix. I'm not sure this is the most elegant way to go about it, but some limited testing shows it working.
Thanks again, Udo. I pushed the patch into the main repo.
BTW, this comment at GenBind.hs line 1662 is no longer valid, isn't it?
-- * we make use of the assertion that `extractCompType' can only return a -- `DefinedET' when the declaration is a pointer declaration
When else do you think DefinedET is produced? Manuel
participants (3)
-
Duncan Coutts
-
Manuel M T Chakravarty
-
Udo Stenzel