[C2hs] {# sizeof #} hook going wrong for cases of structs with
embeded arrays.
Duncan Coutts
duncan.coutts at worc.ox.ac.uk
Sat Apr 29 10:28:15 EDT 2006
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
More information about the C2hs
mailing list