gpt4 book ai didi

c - 在为所有枚举值定义大小写后,编译器仍然说 : "control reaches end of non-void function"

转载 作者:太空狗 更新时间:2023-10-29 17:02:06 25 4
gpt4 key购买 nike

写一个简单的评估我遇到了一个有趣的问题。

给定代码:

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 语句具有与 NODELEAF 不同的值。


编辑:我试过这段代码:

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com