在一些遗留代码中,我有很多枚举,以及一个巨大的切换案例.我想测试一下开关是否具有纯枚举类型.无意义的例子:
typedef enum EN
{
EN_0,
EN_1
} EN_T;
typedef enum DK
{
DK_0,
DK_1
} DK_T;
EN_T bar = ...
switch( bar )
{
case EN_0:
...
break;
case DK_1: //<-- mixed type
...
break;
}
Run Code Online (Sandbox Code Playgroud)
我试着编译它gcc with -Wall -Wextra -pedantic,并没有得到任何警告.有关如何测试的任何想法?作为编译器警告或专用测试代码.由于交换机和枚举都有100多个成员,因此它必须是某种程度的通用.
编辑:请注意我不关心这是否合法c,根据C标准.
这是不好的做法,编译器可以警告不良做法或潜在的错误,不会违反标准,if( a = 1)...总是如此,完全合法,但可能是一个错误.
如果枚举上的开关不包含该枚举aso的所有值,我可以使编译器发出警告
如果编译器可以工作,那是首选,但如果像lint或类似的工具可以做到这一点,我也会很开心.
不,您不能将switch case标签限制为特定的显式值enum.(您可以在C++中对C++ 11感兴趣).
如果您能够更改enum值以使它们不相交,那可能对您有所帮助,但仅限于运行时.
好吧,我自己来回答。经过更多研究后,我得出结论,至少 gcc 不会抱怨这一点,我需要使用像 pc-lint 这样的额外程序。
我稍微重写了一下以强调这个问题。
#include <stdio.h>
typedef enum EN
{
ZERO,
ONE
} EN_T;
typedef enum DK
{
EN, /* Danish word for One */
TO /* Danish word for Two */
} DK_T;
char* E2str( EN_T en )
{
char* ret;
switch( en )
{
case ZERO:
ret = "0";
break;
case TO:
ret = "2";
break;
}
return ret;
}
int main( void )
{
printf( "0 = %s\n", E2str( ZERO ) );
printf( "1 = %s\n", E2str( ONE ) );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这将很好地编译,即使使用以下命令也不会出现警告:
gcc -o t.exe t.c -Wall -Wextra -pedantic
输出将是:
0 = 0
1 = 2
Run Code Online (Sandbox Code Playgroud)
It is clear that this output was probably not the intention of the writer. And yes in this small example it is clear and obvious when just looking at the code. But imagine this being a switch with 200+ cases, and the switch contains other switches, and the naming of the enum is not as clear as in my example in the original question. It becomes close to impossible to spot errors like the one in this example.
Also note that by using -Wextra I enable a check in gcc that will warn if I have a switch on an enum, and the cases does not contain all the values in that enum. But because the TO enum has the sane numeric value as ONE, gcc doesn't even complain about missing Enums in switch, apparently it does only look at the numeric value, and not the provided enum for this check.
My test with pc-lint, spotted both
--- Module: t.c (C)
_
case TO:
t.c 23 Warning 408: Type mismatch with switch expression
_
}
t.c 26 Info 787: enum constant 'EN::ONE' not used within switch
Unfortunately this was not the answer I was hoping for, it would be so much nicer to have this done by the compiler, and not by yet another tool.
Still open to give someone else the credit for an better answer.
| 归档时间: |
|
| 查看次数: |
1131 次 |
| 最近记录: |