[m-users.] Lessons to learn from that supposed compiler bug

Zoltan Somogyi zoltan.somogyi at runbox.com
Thu Jan 11 02:31:20 AEDT 2024


On 2024-01-10 21:01 +11:00 AEDT, "Volker Wysk" <post at volker-wysk.de> wrote:
> - More?

I would strongly urge people who need to pass enums between Mercury code
on the one hand and C, C# or Java code on the other hand to use either
foreign_enum pragmas (if the enum type is defined in C, C# or Java) or
foreign_export_enum pragmas (if the enum type is defined in Mercury).
They are described by sections 16.5 and 16.6 of the Mercury reference manual
(in its ROTD version). They make it simple to follow the good practices
Volker lists in his email. For example, io.m in the Mercury standard library
contains this code:

:- type byte_order 
    --->    big_endian
    ;       little_endian.

:- pragma foreign_export_enum("C", byte_order/0,
    [prefix("ML_"), uppercase]).
:- pragma foreign_export_enum("Java", byte_order/0,
    [prefix("ML_"), uppercase]).
:- pragma foreign_export_enum("C#", byte_order/0,
    [prefix("ML_"), uppercase]).

The prefix and uppercase attributes tell Mercury that the
names in C, C# and Java code corresponding to these two
enum values should be ML_BIG_ENDIAN and ML_LITTLE_ENDIAN
respectively.

I also second the recommendation to use enums in C instead of sets of #defined
values, as they communicate intent much more directly, and are less error prone.
I say that even though foreign_export_enum pragmas actually generate
sets of #defined values instead of an enum type. The reason for that
is very simple; when we implemented the pragma, some C compilers
did not yet support enum types.

Zoltan.


More information about the users mailing list