如果我有多个enum,例如:
enum Greetings{ hello, bye, how };
enum Testing { one, two, three };
Run Code Online (Sandbox Code Playgroud)
如何强制使用正确的enum?例如,我不希望有人hello在他们应该使用时使用它们以one获得更好的调试和可读性.
Die*_*Epp 12
在C中,您可以使用样板代码伪造它.
typedef enum { HELLO_E, GOODBYE_E } greetings_t;
struct greetings { greetings_t greetings; };
#define HELLO ((struct greetings){HELLO_E})
#define GOODBYE ((struct greetings){GOODBYE_E})
typedef enum { ONE_E, TWO_E } number_t;
struct number { number_t number; };
#define ONE ((struct number){ONE_E})
#define TWO ((struct number){TWO_E})
void takes_greeting(struct greetings g);
void takes_number(struct number n);
void test()
{
takes_greeting(HELLO);
takes_number(ONE);
takes_greeting(TWO);
takes_number(GOODBYE);
}
Run Code Online (Sandbox Code Playgroud)
这不应该产生任何开销,并产生错误而不是警告:
$ gcc -c -std=c99 -Wall -Wextra test2.c test2.c: In function ‘test’: test2.c:19: error: incompatible type for argument 1 of ‘takes_greeting’ test2.c:20: error: incompatible type for argument 1 of ‘takes_number’
请注意,我没有使用GNU扩展,也没有生成虚假警告.只有错误.另请注意,我使用的是一种与泥土一样古老的GCC版本,
$ gcc --version powerpc-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5493) Copyright (C) 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
这适用于任何支持C99复合文字的编译器.
Clang产生以下警告,这是您可以做的最好的事情(虽然用户可以将警告升级为错误).
enum Greetings { hello, bye, how };
enum Count { one, two, three };
void takes_greeting(enum Greetings x) {}
void takes_count(enum Count x) {}
int main() {
takes_greeting(one);
takes_count(hello);
}
Run Code Online (Sandbox Code Playgroud)
编译器输出:
cc foo.c -o foo
foo.c:8:17: warning: implicit conversion from enumeration type 'enum Count' to different enumeration type 'enum Greetings' [-Wenum-conversion]
takes_greeting(one);
~~~~~~~~~~~~~~ ^~~
foo.c:9:14: warning: implicit conversion from enumeration type 'enum Greetings' to different enumeration type 'enum Count' [-Wenum-conversion]
takes_count(hello);
~~~~~~~~~~~ ^~~~~
Run Code Online (Sandbox Code Playgroud)
如果用户要忽略编译器中的错误和警告,那么您无法帮助他们.