Mar*_*sen 8 c enums gcc static-analysis switch-statement
写一个简单的评估我遇到了一个有趣的问题.
鉴于代码:
enum node_type {LEAF, NODE};
struct tree_elm_t {
enum node_type type;
union {
struct tree_node_t node;
struct tree_leaf_t leaf;
} datum;
};
int parse_leaf(struct tree_leaf_t leaf);
int parse_node( struct tree_node_t node );
int parse_tree( struct tree_elm_t* tree );
....
int parse_tree( struct tree_elm_t* tree ) {
switch( tree->type ) {
case NODE: return parse_node(tree->datum.node);
case LEAF: return parse_leaf(tree->datum.leaf);
}
}
Run Code Online (Sandbox Code Playgroud)
我很惊讶地看到gcc抱怨缺少控制流选项:
example.c: In function 'parse_tree':
example.c:54: warning: control reaches end of non-void function
Run Code Online (Sandbox Code Playgroud)
通过将返回值存储在如下变量中可以解决流问题:
int parse_tree( struct tree_elm_t* tree ) {
int sum;
switch( tree->type ) {
case NODE: sum = parse_node(tree->datum.node); break;
case LEAF: sum = parse_leaf(tree->datum.leaf); break;
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
然而,我确实找到了原始代码很多,有没有办法使gcc接受原始代码 - (我想静态分析,以实现我的代码是有效的,干净).
编辑:
我可能有点不清楚.
让我说我编译以下代码:
int parse_tree( struct tree_elm_t* tree ) {
int sum;
switch( tree->type ) {
case NODE: sum = parse_node(tree->datum.node); break;
// case LEAF: sum = parse_leaf(tree->datum.leaf); break;
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
gcc会给我一个警告:
example.c: In function 'parse_tree':
example.c:51: warning: enumeration value 'LEAF' not handled in switch
Run Code Online (Sandbox Code Playgroud)
这意味着gcc对交换机中的值有选择感,并且我已经注释了LEAF案例.这意味着gcc也知道,当通过交换机时,每个案例都在进行检查.那么为什么声明:
control reaches end of non-void function
Run Code Online (Sandbox Code Playgroud)
它是否缺乏gcc中缺乏的静态分析系统 - 或者语言功能?
您的编译器抱怨,因为函数逻辑中的所有路径都应返回一个值(如此函数的原型所规定的):
int parse_tree( struct tree_elm_t* tree ) {
switch( tree->type ) {
case NODE: return parse_node(tree->datum.node);
case LEAF: return parse_leaf(tree->datum.leaf);
default: return 0; // <-- problem solved
}
}
Run Code Online (Sandbox Code Playgroud)
编译器(在这个答案中和我一样)更侧重于语法而不是代码的语义.
虽然您已定义enum node_type {LEAF, NODE},但您的编译器不希望依赖此约束并接受typein tree->type语句具有不同的值NODE或者LEAF无论如何具有不同值的可能性.
编辑:我试过这段代码:
enum node_type {LEAF, NODE};
struct node { enum node_type type; };
int parse_tree( struct node* n ) {
switch( n->type ) {
case NODE: return 1;
case LEAF: return 2;
}
}
int main() {
struct node n;
printf("%d", parse_tree(&n));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在ideone上,结果如下:
(gcc-4.8.1,编译为"C")~ http://ideone.com/b0wdSk :代码有效,输出2
(gcc-4.8.1,编译为"C++") ~ http://ideone.com/OPH5Ar:与"C"相同
(gcc-4.8.1,编译为"C99严格")~ http://ideone.com/ou71fe:因以下原因无效:
错误:控件到达非void函数的结尾[-Werror = return-type]
为了支持Martin Kristiansen关于为枚举赋值的任何积分值的观点,我尝试struct node n; n.type = 7;使用相同的代码并使用"C"但也使用"C99严格",编译器根本不会抱怨.但是"C++"给出:
错误:从'int'到'node_type'的无效转换[-fpermissive]