haskell / c2hs

c2hs is a pre-processor for Haskell FFI bindings to C libraries
http://hackage.haskell.org/package/c2hs
Other
198 stars 50 forks source link

size and offset errors with bit-fields and typedefs #168

Open facundominguez opened 8 years ago

facundominguez commented 8 years ago

This happens on windows with 32-bit version of ghc-7.10.3, c2hs-0.28.1, gcc-5.2.0.

gcc and c2hs disagree on the size of the bitfields0 struct below.

// bitfields.h
typedef unsigned int an_int;
typedef struct {
    an_int b0  : 5;
    unsigned int b1 : 27;
} bitfields0;

typedef struct {
    bitfields0 a;
    unsigned int* p0;
    unsigned int* p1;
    unsigned int* p2;
} bitfields;

C test program

// bitfields.c
#include "bitfields.h"
#include <stdio.h>

int main(int argc, char** argv) {
    bitfields b;
    printf("size of bitfields: %lu\n",sizeof(bitfields));
    printf("offset of p1: %d\n"
          , (int)(((void*)&b.p1) - (void*)&b));
    return 0;
}

Output:

$ ./a.exe
size of bitfields: 16
offset of p1: 8

c2hs program

-- Bitfields.chs
module Bitfields where

import Foreign.C.Types
#include "bitfields.h"

s :: Int
s = {#sizeof bitfields #}

o :: Ptr () -> IO CUInt
o = {#get bitfields->p1 #}

Output:

module Bitfields where
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.Ptr as C2HSImp
import qualified Foreign.Storable as C2HSImp

import Foreign.C.Types

s :: Int
s = 20

o :: Ptr () -> IO CUInt
o = (\ptr -> do {C2HSImp.peekByteOff ptr 12 :: IO (C2HSImp.Ptr C2HSImp.CUInt)})