我正在浏览一些 netfilter 代码。
我不知道任何指定具有重复名称的枚举成员的 C 规则。
enum ctattr_type {
CTA_UNSPEC,
CTA_TUPLE_ORIG,
CTA_TUPLE_REPLY,
CTA_STATUS,
CTA_PROTOINFO,
CTA_HELP,
CTA_NAT_SRC,
CTA_TIMEOUT,
CTA_MARK,
CTA_COUNTERS_ORIG,
CTA_COUNTERS_REPLY,
CTA_USE,
CTA_ID,
CTA_NAT_DST,
CTA_TUPLE_MASTER,
CTA_NAT_SEQ_ADJ_ORIG,
CTA_NAT_SEQ_ADJ_REPLY,
CTA_SECMARK,
CTA_ZONE,
CTA_SECCTX,
CTA_TIMESTAMP,
CTA_MARK_MASK,
CTA_LABELS,
CTA_LABELS_MASK,
__CTA_MAX,
CTA_UNSPEC,
CTA_TUPLE_ORIG,
CTA_TUPLE_REPLY,
CTA_STATUS,
CTA_PROTOINFO,
CTA_HELP,
CTA_NAT_SRC,
CTA_TIMEOUT,
CTA_MARK,
CTA_COUNTERS_ORIG,
CTA_COUNTERS_REPLY,
CTA_USE,
CTA_ID,
CTA_NAT_DST,
CTA_TUPLE_MASTER,
CTA_NAT_SEQ_ADJ_ORIG,
CTA_NAT_SEQ_ADJ_REPLY,
CTA_SECMARK,
CTA_ZONE,
CTA_SECCTX,
CTA_TIMESTAMP,
CTA_MARK_MASK,
CTA_LABELS,
CTA_LABELS_MASK,
__CTA_MAX,
CTA_UNSPEC,
CTA_TUPLE_ORIG,
CTA_TUPLE_REPLY,
CTA_STATUS,
CTA_PROTOINFO,
CTA_HELP,
CTA_NAT_SRC,
CTA_TIMEOUT,
CTA_MARK,
CTA_COUNTERS_ORIG,
CTA_COUNTERS_REPLY,
CTA_USE,
CTA_ID,
CTA_NAT_DST,
__CTA_MAX
}
Run Code Online (Sandbox Code Playgroud)
这里 __CTA_MAX 出现多次。事实上,许多其他属性枚举被重复定义。
当我打印 __CTA_MAX 值时,它会打印第一个出现的枚举值。 23
那么其他 __CTA_MAX 值有什么用呢。其他重复属性有什么用。
来自 C11 标准(取自http://port70.net/~nsz/c/c11/n1570.html#6.7.2.2):
6.7.2.2 枚举说明符
...
脚注:
127) 因此,在同一作用域中声明的枚举常量的标识符应彼此不同,并且与普通声明符中声明的其他标识符不同。
因此,在一个枚举中重复使用相同的枚举常量(甚至在同一范围内的两个不同枚举中使用相同的枚举常量)在 C 中是无效的。
您看到的很可能是 Doxygen 创建的人工制品,并不反映源代码中的实际定义。
来自http://git.netfilter.org 的linux_nfnetlink_conntrack.h 中的定义只是
enum ctattr_type {
CTA_UNSPEC,
CTA_TUPLE_ORIG,
CTA_TUPLE_REPLY,
CTA_STATUS,
CTA_PROTOINFO,
CTA_HELP,
CTA_NAT_SRC,
#define CTA_NAT CTA_NAT_SRC /* backwards compatibility */
CTA_TIMEOUT,
CTA_MARK,
CTA_COUNTERS_ORIG,
CTA_COUNTERS_REPLY,
CTA_USE,
CTA_ID,
CTA_NAT_DST,
CTA_TUPLE_MASTER,
CTA_SEQ_ADJ_ORIG,
CTA_NAT_SEQ_ADJ_ORIG = CTA_SEQ_ADJ_ORIG,
CTA_SEQ_ADJ_REPLY,
CTA_NAT_SEQ_ADJ_REPLY = CTA_SEQ_ADJ_REPLY,
CTA_SECMARK, /* obsolete */
CTA_ZONE,
CTA_SECCTX,
CTA_TIMESTAMP,
CTA_MARK_MASK,
CTA_LABELS,
CTA_LABELS_MASK,
__CTA_MAX
};
#define CTA_MAX (__CTA_MAX - 1)
Run Code Online (Sandbox Code Playgroud)