写一个简单的评估我遇到了一个有趣的问题。
给定代码:
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);
}
}
我很惊讶地看到 gcc 提示缺少控制流选项:
example.c: In function 'parse_tree':
example.c:54: warning: control reaches end of non-void function
流问题可以通过将返回值存储在变量中来解决,如下所示:
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;
}
不过我确实发现原始代码更清晰,有没有办法让 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;
}
gcc 会给我一个警告:
example.c: In function 'parse_tree':
example.c:51: warning: enumeration value 'LEAF' not handled in switch
这意味着 gcc 了解开关中值的选项,以及我已经注释掉 LEAF 案例的事实。这意味着 gcc 也知道在通过 switch 时会检查每个案例。那么为什么声明:
control reaches end of non-void function
它是否缺少 gcc 中缺少的静态分析系统 - 或语言功能?
最佳答案
你的编译器在提示,因为你函数逻辑中的所有路径都应该返回一个值(正如这个函数的原型(prototype)所规定的):
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
}
}
编译器(就像我在这个答案中一样)更关注代码的语法而不是语义。
虽然您已经定义了 enum node_type {LEAF, NODE}
,但您的编译器不想依赖此约束并接受 type
的可能性 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;
}
在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 strict”)~ http://ideone.com/ou71fe : 无效因为:
error: control reaches end of non-void function [-Werror=return-type]
并支持Martin Kristiansen关于为枚举分配任何整数值的观点是有效的,我已经尝试过 struct node n; n.type = 7;
使用相同的代码和“C”以及“C99 strict”,编译器根本不会提示。但是“C++”给出:
error: invalid conversion from ‘int’ to ‘node_type’ [-fpermissive]
关于c - 在为所有枚举值定义大小写后,编译器仍然说 : "control reaches end of non-void function",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18680378/