简体   繁体   中英

possible? Typedef enum in C without members, add members in another file

Problem

For a library im writing the user has to define different input values, as in

enum {
    A_VALUE1,
    A_VALUE2
};
enum {
    B_VALUE1,
    B_VALUE2
};

These values can then be used as params for library functions, eg:

library_function( context_handle_1, A_VALUE1 );
library_function( context_handle_2, B_VALUE1 );

What i would like to do is:

  • typedef the enum (more clear, better readability, compiler warnings) but
  • have dont want multiple implementations of library_function and therefore just one type for the enum, while
  • the library user creates the actual values for the enums and can use
  • multiple enums for different library instances.

Tried A

typedef enum my_enum_type;

my_enum_type {
   IDENTIFIER_SET_A
}

my_enum_type {
   IDENTIFIER_SET_B
}

error: must use 'enum' tag to refer to type 'my_type'.


Tried B

Use preprocessor macros to create a unique variable type for each enum:

#define MY_ENUM(name, ...) \
typedef enum name##_enum_type {
    __VA_ARGS__,
    name##_COUNT
};

This will require a separate library function for each name or a type conversion on a function call. The additional name##_COUNT could come in handy, but then i need to know name to access it.


Tried C

Using preprocessor macros to create multiple datatypes, then wrap the function call in a #define to typecast it back, like

#define VALUES(...) typedef enum __FILE__##__LINE__## { __VA_ARGS__ } __FILE__##__LINE__##_t
#define lib_run(func, value) func((my_enum_type)value)

typedef int my_enum_type;

func(my_enum_type value) {
   do_something();
}

I tried using something like __FILE__ or __LINE__ to create an automated name that is both unique and does not need to be given by the user. But the qoutes in __FILE__ kill this approach, as it generates invalid variable names.


Question

What could be a valid way to

  • create an enum type with typedef for a library
  • do not add any identifiers to this type yet, but
  • allow a library user to create enums with identifiers using this type
  • pass any value of these enum to the same function (bonus: without type conversion)


You could create a forward declaration of the type using

enum tag_name;

then create a typedef using this incomplete definition with

typedef enum tag_name my_enum_type;

and expose those in a header file, and then complete the definition in a.c file using

enum tag_name { ... };

What you cannot do is define the type as

enum tag_name { ENUM1, ENUM2 };

and then later on add

enum tag_name { ENUM3 };

The type is complete after the closing } of the first definition - you can't add any more enumeration constants after that point. C just doesn't work like that.

I'm not fond of using typedef just to create a new name - the user of the type still needs to know it's an enum type (or at least that it's an integral value). The abstraction is "leaky" and just adds clutter. Either create a complete abstraction where the user of the type does not have to be aware of how it's implemented, or don't use an abstraction at all.

enum s are for readability and for the compiler.

An easy way is for the header file for the library to contain the enum definition (the code calling the library also needs to know the enum definition.)

By having the enum definition in the header file (note, not an instance of the enum , just the definition.) any file that includes that header file can access the library function and pass valid enum parameters

Strongly suggest to NOT turn that enum definition into a typedef name

Do notice the difference between a enum definition and an instance of that enum

Instance:

enum myEnum enumInstance;

Definition:

enum myEnum { ... };

Anonymous:

enum { ... };

All where the ... is the list of name=value pairs. separated by commas.

for flexibility, do NOT combine the definition with an instance, IE

enum myEnum { ... } enumInstance;

or

enum { ... } enumInstance;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM