
Hmm, we're looking at this. However, I don't really know what C is or is not supposed to do here. Given char fooble ( ... ) { return 'z'; } on an x86, 'z' will be returned at the lowest 8 bits in %eax. What I don't know is, is the C compiler obliged to clear the upper 24 bits of %eax, or does that onus fall on the callee? Also, I don't even know where to look for the specification of details of the C calling conventions. Anyone got a clue? J | -----Original Message----- | From: Ashley Yakeley [mailto:ashley@semantic.org] | Sent: Monday, August 06, 2001 1:34 AM | To: GHC List | Subject: GHC FFI Return Type Bug | | | Has anyone else come across this? I've only tried this with | Word8 but I | suspect this is a problem with all return types smaller than | four bytes. | | I've entered this as GHC bug #448104. | <http://sourceforge.net/tracker/index.php?func=detail&aid=4481 | 04&group_id=8 | 032&atid=108032> | | Here's the C code: | | extern "C" | { | unsigned char foo(); | } | | inline void use(const char* s) | { | } | | unsigned char foo() | { | const char* s = ""; | use(s); | return 0; | } | | ...and the Haskell looks something like this: | | foreign import foo :: IO Word8 | | do { | w8 <- foo; | putStrLn (show (w8 :: Word8)); | } | | ...and the result is this: | 1074803712 | | Kind of an unusual Word8 value! But note that the low byte of | this value | is zero. | | My setup: | | $ ghc -v | Glasgow Haskell Compiler, Version 5.00, for Haskell 98, | compiled by GHC | version 5.00 | Using package config file: /usr/lib/ghc-5.00/package.conf | Hsc static flags: -static -fignore-interface-pragmas | -fomit-interface-pragmas -fdo-lambda-eta-expansion -flet-no-escape | | $ uname -a | Linux server 2.2.19pre17 #1 Tue Mar 13 22:37:59 EST 2001 i686 unknown | | | -- | Ashley Yakeley, Seattle WA | | | _______________________________________________ | Glasgow-haskell-users mailing list | Glasgow-haskell-users@haskell.org | http://www.haskell.org/mailman/listinfo/glasgo| w-haskell-users |

"Julian Seward (Intl Vendor)"
Hmm, we're looking at this. However, I don't really know what C is or is not supposed to do here. Given
char fooble ( ... ) { return 'z'; }
on an x86, 'z' will be returned at the lowest 8 bits in %eax. What I don't know is, is the C compiler obliged to clear the upper 24 bits of %eax, or does that onus fall on the callee?
Yes, the callee is required to narrow <expr> in 'return <expr>;' to fit that of the specified return type -- see 9.8 of Harbison and Steele. So, a C compiler that cause f() to return 0x7fffffff for the following, unsigned char g() { return 0x7fffffff; } unsigned int f() { return g(); } is in the wrong. [Notice that narrowing for signed integral types is undefined in ISO C, but most current-day compilers implement such narrowing ops the same way, i.e., by masking off excess bits.]
Also, I don't even know where to look for the specification of details of the C calling conventions. Anyone got a clue?
Harbison & Steele Chapters 6 and 9 cover the conversion rules that apply to functions (and other expressions). As you no doubt already know, lower-level details are the domain of a platform's ABI. Sounds to me like unboxed sized Words and Ints is the (unavoidable) way to go. --sigbjorn
participants (2)
-
Julian Seward (Intl Vendor)
-
Sigbjorn Finne