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 library_function
and therefore just one type for the enum, whileTried 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
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.