Comment #0 by andrej.mitrovich — 2024-06-30T08:29:14Z
This is a small snippet from a C++ library blend2d that can be used in C.
Here's the header file lib.h:
---
#ifdef __cplusplus
#define BL_DEFINE_CONST static constexpr
#define BL_DEFINE_ENUM(NAME) enum NAME : uint32_t
#define BL_FORCE_ENUM_UINT32(ENUM_VALUE_PREFIX)
#else
#define BL_DEFINE_CONST static const
#define BL_DEFINE_ENUM(NAME) typedef enum NAME NAME; enum NAME
#define BL_FORCE_ENUM_UINT32(ENUM_VALUE_PREFIX) ,ENUM_VALUE_PREFIX##_FORCE_UINT = 0xFFFFFFFFu
#endif
BL_DEFINE_ENUM(BLObjectType) {
BL_OBJECT_TYPE_RGBA = 0,
BL_OBJECT_TYPE_RGBA32 = 1,
};
int blArrayInit(BLObjectType arrayType);
---
Running the VC preprocessor:
---
cl /P /TC /EP /Filib.c lib.h
---
Generates this code:
---
typedef enum BLObjectType BLObjectType; enum BLObjectType {
BL_OBJECT_TYPE_RGBA = 0,
BL_OBJECT_TYPE_RGBA32 = 1,
};
int blArrayInit(BLObjectType arrayType);
---
This cannot be imported with DMD:
---
$ dmd -o- lib.c
lib.c(5): Error: cannot have parameter of opaque type `BLObjectType` by value
---
Moving the type def /after/ the enum definition fixes this as expected.
But it looks like existing C compilers (other than DMD's) seem to support this syntax.
Both VC and GCC work with these typedefs. I'm not sure what they do underneath the hood to make this work.
Comment #1 by andrej.mitrovich — 2024-06-30T08:35:39Z
For reference I managed to find a very simple fix. I replaced the macro from:
---
#define BL_DEFINE_ENUM(NAME) typedef enum NAME NAME; enum NAME
---
to:
---
#define BL_DEFINE_ENUM(NAME) enum NAME
---
And then the preprocessed file can be imported into DMD nicely.
Comment #2 by robert.schadek — 2024-12-13T19:36:08Z