Hi all, A relatively mundane question: Is there a preferred means of writing a foreign import declaration for a C function with a prototype that takes an "enum" argument? i.e., in C we have: enum bar { GOOD, BAD }; void foo(enum bar x); I recall from some sessions with gdb some years ago that most C compilers encode enums as if they were unsigned short values (i.e. 16 bits on most platforms). Does anyone know off hand: - Is it a safe, portable assumption that enums will always be encoded as an unsigned short or 16-bit word? - If so, should one prefer "Word16" or "UShort" on the Haskell side for the foreign import declaration? - If not, then how should enum values be declared in the FFI? Appologies if the FFI addresses this issue and I have overlooked it. Thanks, -antony -- Antony Courtney Grad. Student, Dept. of Computer Science, Yale University antony@apocalypse.org http://www.apocalypse.org/pub/u/antony
On 16-Oct-2002, Antony Courtney <antony@apocalypse.org> wrote:
Does anyone know off hand:
- Is it a safe, portable assumption that enums will always be encoded as an unsigned short or 16-bit word?
No, that assumption is not safe or portable.
- If not, then how should enum values be declared in the FFI?
-- Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit The University of Melbourne | of excellence is a lethal habit" WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
- If not, then how should enum values be declared in the FFI?
What you need to do is run a little autoconf-like program which constructs a program containing a suitable example, runs it through a C compiler and tells you what's going on. hsc comes very close but I'm not certain if it does exactly what you need. If not, compiling and running this program should tell you: #include <stdio.h> enum test {X,Y}; main() { printf("module EnumSize(enumSize) where\n"); printf("enumSize :: Int\n"); printf("enumSize = %d\n", sizeof(enum test)); } Variants on this theme are figuring out whether it is signed or unsigned and the size in bits and generating a Haskell type synonym. Looking at hsc-generated C programs is a great source of tricks (I stole a few for the Hugs configure code). -- Alastair
- If not, then how should enum values be declared in the FFI?
What you need to do is run a little autoconf-like program which constructs a program containing a suitable example, runs it through a C compiler and tells you what's going on.
hsc comes very close but I'm not certain if it does exactly what you need. If not, compiling and running this program should tell you:
Hmm, careful. The C compiler is free to be clever, and use a char if there are <=256 elements in the enum, and short or int otherwise. You want to know the size of your particular enum, not any random enum. (betraying my age, but didn't Turbo C do this?) --KW 8-) -- Keith Wansbrough <kw217@cl.cam.ac.uk> http://www.cl.cam.ac.uk/users/kw217/ University of Cambridge Computer Laboratory.
I am pretty sure that ISO C says that enums are equivalant to ints always. of course, not all implementations may be ISO C compliant. John On Thu, Oct 17, 2002 at 10:01:56AM +0100, Keith Wansbrough wrote:
- If not, then how should enum values be declared in the FFI?
What you need to do is run a little autoconf-like program which constructs a program containing a suitable example, runs it through a C compiler and tells you what's going on.
hsc comes very close but I'm not certain if it does exactly what you need. If not, compiling and running this program should tell you:
Hmm, careful. The C compiler is free to be clever, and use a char if there are <=256 elements in the enum, and short or int otherwise. You want to know the size of your particular enum, not any random enum.
(betraying my age, but didn't Turbo C do this?)
--KW 8-) -- Keith Wansbrough <kw217@cl.cam.ac.uk> http://www.cl.cam.ac.uk/users/kw217/ University of Cambridge Computer Laboratory.
_______________________________________________ FFI mailing list FFI@haskell.org http://www.haskell.org/mailman/listinfo/ffi
-- --------------------------------------------------------------------------- John Meacham - California Institute of Technology, Alum. - john@foo.net ---------------------------------------------------------------------------
On Thu, Oct 17, 2002 at 02:25:44AM -0700, John Meacham wrote:
I am pretty sure that ISO C says that enums are equivalant to ints always. of course, not all implementations may be ISO C compliant. John
Right. C99#6.4.4.3: [...] [#2] An identifier declared as an enumeration constant has type int. Cheers, M/
On 17-Oct-2002, Michael Weber <michaelw@foldr.org> wrote:
On Thu, Oct 17, 2002 at 02:25:44AM -0700, John Meacham wrote:
I am pretty sure that ISO C says that enums are equivalant to ints always. of course, not all implementations may be ISO C compliant. John
Right.
No, this is wrong.
C99#6.4.4.3: [...] [#2] An identifier declared as an enumeration constant has type int.
The enumeration constants have type `int'. However, the enumeration type itself is a different type. The enumeration type need not have the same size or representation as int. | 6.7.2.2 Enumeration specifiers | | [#4] Each enumerated type shall be compatible with char, a | signed integer type, or an unsigned integer type. The | choice of type is implementation-defined, but shall be | capable of representing the values of all the members of the | enumeration. | Footnote 108: | An implementation may delay the choice of which integer | type until all enumeration constants have been seen. -- Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit The University of Melbourne | of excellence is a lethal habit" WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
Antony Courtney <antony@apocalypse.org> wrote,
A relatively mundane question:
Is there a preferred means of writing a foreign import declaration for a C function with a prototype that takes an "enum" argument?
i.e., in C we have:
enum bar { GOOD, BAD };
void foo(enum bar x);
That's exactly the kind of scenario for which I have written C->Haskell: http://www.cse.unsw.edu.au/~chak/haskell/c2hs Using C->Haskell, you write into the binding module {#enum bar as Bar#} run it through the tool and get a Haskell data definition for `Bar', so that you can safely marshal between C's bar and Haskell's Bar. (See also the corresponding section in the manual <http://www.cse.unsw.edu.au/~chak/haskell/c2hs/docu/c2hs-3.html#ss3.5>.) Manuel
participants (7)
-
Alastair Reid -
Antony Courtney -
Fergus Henderson -
John Meacham -
Keith Wansbrough -
Manuel M T Chakravarty -
Michael Weber