Opened 9 years ago

Last modified 3 years ago

#2926 new bug

Foreign exported function returns wrong type

Reported by: fasta Owned by:
Priority: low Milestone:
Component: Compiler (FFI) Version: 6.10.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: #3238 Differential Rev(s):
Wiki Page:


I call foo, foreign export ccall foo :: Int -> IO CInt, from C code like this: printf("%d\n", (int)foo((HsInt32)2500)); but when I remove the (int) cast, gcc complains (warnings, not errors) because it thinks that the thing that foo returns is a HsInt32, and not a C int. The type for foo clearly specifies it is a CInt.

The bug is that GHC is probably not generating a CInt, but a HsInt32.

{-# LANGUAGE ForeignFunctionInterface #-}
-- name this file ExportHaskellToCStruct.hs
module ExportHaskellToCStruct(foo) where
import Foreign.C
import Data.List
foreign export ccall foo :: Int -> IO CInt

foo = return . genericLength .  f

f :: Int -> [Int]
f 0 = []
f n = n:(f (n-1))
#include <stdio.h>                                                                                                                                           
#include "/correctpathto/include/HsFFI.h"         /*    FIX PATH for your installation */                                                                                                          
#define __GLASGOW_HASKELL__                                                                                                                                  

#include "ExportHaskellToCStruct_stub.h"

extern void __stginit_ExportHaskellToCStruct(void);

int main(int argc, char *argv[])
  int i;

  hs_init(&argc, &argv);

  for (i = 0; i < 5; i++) {
    printf("%d\n", (int)foo((HsInt32)2500)); 

  return 0;
gcc --version
gcc (Ubuntu 4.3.2-1ubuntu11) 4.3.2

Change History (3)

comment:1 Changed 9 years ago by simonmar

difficulty: Unknown

I can't reproduce the problem here - gcc compiles the file without complaint, even with -Wall -Werror, on both x86 and x86_64. I wouldn't expect this to go wrong, because HsInt32 is the same type as int.

comment:2 Changed 9 years ago by simonmar

Milestone: _|_
Priority: normallow

Oh, I see.

In fact HsInt32 happens to be long on x86, so gcc warns about its use with the %d format in printf, even though on this architecture long is the same size as int. gcc is complaining about a portability problem, but we know there isn't one. In almost every other way, HsInt32 is interchangeable with int.

We could make HsInt32 the same as int, but then the exact same problem would crop up with CLong.

Sigh. It's a pain to make GHC emit a real int here, because GHC doesn't know anything special about the CInt type, as far as GHC is concerned it's just a newtype of Int32 (or whatever).

I'm making this bug low prio, because there are easy workarounds and it's hard to fix.

comment:3 Changed 3 years ago by thomie

Type of failure: None/Unknown
Note: See TracTickets for help on using tickets.