可能吗?C语言中的Typedef枚举没有成员,在另一个文件中添加成员。

问题描述 投票:0回答:2

问题

对于一个正在编写的库,用户必须定义不同的输入值,如

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

这些值可以作为库函数的参数,例如。

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

我想做的是:

  • typedef 这个... enum (更清晰,更好的可读性,编译器警告),但...。
  • 不希望有多个实现的 library_function 因此只有一个类型的枚举,而
  • 库用户为枚举创建实际值,并可以使用
  • 不同库实例的多个枚举。

尝试了A

typedef enum my_enum_type;

my_enum_type {
   IDENTIFIER_SET_A
}

my_enum_type {
   IDENTIFIER_SET_B
}

错误:必须使用'enum'标签来引用类型'my_type'。


尝试了B

使用预处理器宏为每个枚举创建一个独特的变量类型。

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

这将需要为每个枚举建立一个单独的库函数 name 或函数调用的类型转换。额外的名字##_COUNT可以派上用场,但是我需要知道 name 来访问它。


尝试了C

使用预处理程序宏创建多个数据类型,然后将函数调用包裹在一个 #define 把它打回去,就像

#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();
}

我试着用了一些东西,比如 __FILE____LINE__ 来创建一个既独特又不需要用户给出的自动名称。但在 __FILE__ 杀死这种方法,因为它会生成无效的变量名。


问题

什么是有效的方式来

  • 为一个库创建一个类型为typedef的枚举类型。
  • 还没有给这个类型添加任何标识符,但是
  • 允许库用户使用此类型创建带有标识符的枚举。
  • 将这些枚举的任意值传递给同一个函数(奖励:无需类型转换


c enums typedef preprocessor
2个回答
1
投票

你可以使用以下方法创建一个类型的前向声明

enum tag_name;

然后创造 typedef 用这个 不完整 定义与

typedef enum tag_name my_enum_type;

并在头文件中公开这些内容,然后在.c文件中使用

enum tag_name { ... };

您的 不能 要做的就是把类型定义为

enum tag_name { ENUM1, ENUM2 };

再加

enum tag_name { ENUM3 };

类型是 完整 收盘后 } 的第一个定义--在那之后你不能再添加任何枚举常量。 C语言不是这样工作的。

我不喜欢使用 typedef 只是 来创建一个新的名称--该类型的用户仍然需要知道它是一个 enum 类型(或至少它是一个积分值)。 这种抽象是 "漏网之鱼",只会增加杂乱无章。 要么创建一个 完整 抽象,类型的用户不需要知道它是如何实现的,或者根本不使用抽象。


1
投票

enums是为了可读性和编译器。

一个简单的方法是在库的头文件中包含了 enum 定义(调用该库的代码也需要知道该库的 enum 定义)。)

通过拥有 enum 定义(注意,不是头文件中的 enum的定义)任何包含该头文件的文件都可以访问库函数并传递有效的 enum 参数

强烈建议不要将 enum 定义为 typedef 名称

请注意以下两个方面的区别 enum 定义和该定义的一个实例 enum

实例。

enum myEnum enumInstance;

定义:

enum myEnum { ... };

无名氏。

enum { ... };

所有的地方 ... 是name=value对的列表,用逗号分隔。

为灵活起见,不要将定义与实例结合起来,如

enum myEnum { ... } enumInstance;

enum { ... } enumInstance;
© www.soinside.com 2019 - 2024. All rights reserved.