C 使用函数返回值进行错误检查和/或异常处理的技术是否正确?
我继承了一个C系统,它使用函数返回值来检查错误和异常;大概是这样的:C 使用函数返回值进行错误检查和/或异常处理的技术是否正确?,c,function,error-handling,exception-handling,return-value,C,Function,Error Handling,Exception Handling,Return Value,我继承了一个C系统,它使用函数返回值来检查错误和异常;大概是这样的: #define OK 1 int create_cheese(const char * myType, float myCost, char * myCheese) { // Do Stuff... if // everything looks good return 1; else return // error/exception code } int main() {
#define OK 1
int create_cheese(const char * myType, float myCost, char * myCheese) {
// Do Stuff...
if // everything looks good
return 1;
else
return // error/exception code
}
int main() {
rc = create_cheese("cheddar", 12.99, &cheese);
if (rc != OK) { exit(rc); }
return 1;
}
这被认为是正确的C技术吗
这些功能不是很实用。换句话说,它们不使用函数返回值作为与程序执行相关的有意义的数据;它们用于错误和异常处理。谢谢,基思:^) < p>是的,这是处理错误的完全有效的方法,特别是因为C没有异常,如C++或java。p> 检查返回值以查看函数是否成功,并使用参数从函数中获取信息。很多库函数都是以这种方式工作的,因此它是C中众所周知的idoim 您还可以混合返回有意义的值和错误代码。例如,
write
库函数返回读取的字节数,如果发生错误,则返回-1。在发生错误的情况下,它还会设置包含实际错误代码的全局errno
这被认为是正确的C技术吗
我在C语言或标准库中没有找到匹配的并行成功返回1
C至少有6种不同的错误通信方式。下面列出了许多
OP发布的技术是返回错误/成功状态的变体
它有两个弱点
是一个太常见的标识符,可能会与其他代码冲突。太容易找到定义为0的OK
OK
- 相反的零度<代码>正常因为0更常见
各种C错误/异常/不愉快的路径处理
- 返回错误/成功(不是数据,但可能是错误数据)
- Success为0,否则返回一个非零的
:许多errno\t
函数。(类似于OP的——但非零成功)…\u s()
- 成功为0,否则为非零<代码>删除(),升高()
- Success为0,否则返回一个非零的
- 返回数据-少数(可能只有一个)值表示错误/特殊
不正确,否则为指针<代码>fgets()、setlocale()、bsearch()NULL
可能不正确,否则为指针<代码>mallocNULL
- 0不好,其他各种都好<代码>fread()
- -1是坏的,其他各种都是好的<代码>时间(),fseek()
-负数。0或更多是好的<代码>fgetc()EOF
其他一些FP\u ILOGB0,FP\u ILOGBNAN
<代码>ilogb()int
- 任何负数都是不好的,否则值将提供信息<代码>printf()
- 最大的几个值具有特殊含义,否则一些值不带符号<代码>mbrtoc16()
- 通过状态/实例对象:许多I/O函数返回
,以指示文件结束或I/O错误。用于确定细节的其他函数EOF
,feof()
ferror()
- 全球的
- 错误代码
:errno
strtol()
- 浮点环境:
fegetexceptflag()
- 错误代码
- 非数字:NaN在错误代码和值之间徘徊不定<代码>日志(负x),atanh(x大于1)
- UB:不以指定方式处理错误:例如
1/0
我在标准C库中没有看到的一种样式是其他库,它是
bool foo(…,int*error\u code)
-传递是存储/更新错误详细信息的地方。这是正确的方法,但您可以遵循现有宏常量EXIT\u SUCCESS
(=0)和EXIT\u FAILURE
(=-1)的规则。所以我建议返回一个值!=0出现错误时。由于C不支持异常,在函数调用后测试错误的唯一方法是检查指定的错误保持变量。有几种方法可以做到这一点:
从函数返回错误/成功指示(即errno\u t foo(int bar);
)
将错误/成功指示作为输出指针参数(即void foo(int bar,errno\t*error\u code);
)
使用操作系统错误指示器(即Windows上的SetLastError
,或errno
)
我是方法#2的粉丝,因为很难忽略以下错误参数:
errno_t err;
myfunction(100, &err);
而不是:
errno_t err = myfunction(100); // You could just as easily not assign the return value
C中的约定(在标准中几乎正式化)是返回0表示成功。所以你的返回1是特殊的,应该改变
这可以扩展为故障时返回负值,接近故障时返回正值
当从main
返回时,您应该假设操作系统只处理返回值的8位,并且可能也不带符号,这与为失败返回负数是矛盾的!这就是标准的好处:有这么多可供选择。我给你一美元来列举这六种方法。说真的,我想知道。@kmiklas上周的最新帖子有一些-没有找到,我将列出一些..我知道你知道这一点,但从技术上讲,0.0/0.0
是未定义的,尽管IEEE754定义了它。我会将所有返回错误状态(x是好的,y是坏的)聚集到一个类别中。这里的“几乎”是:Per:"... 如果status的值为零或EXIT\u SUCCESS
。“我想找到一个不将EXIT\u SUCCESS
定义为零的C实现。@AndrewHenle:是的,这真的很烦人。感谢你花时间在标准中找到这一点。我知道它是存在的