扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
#include <stdio.h>//在标准C里被替换成#include <cstdio> FILE *f = fopen("blarney.txt", "r"); std::FILE *f = std::fopen("blarney.txt", "r");//or the more C-esque #include <cstdio> using namespace std; FILE *f = fopen("blarney.txt", "r"); |
Before you scoff, consider that some exceptions betray a condition so severe that reasonable recovery is unlikely anyway. Perhaps the best example is malloc of a small object returning NULL. If the free store manager can't scrape together a few spare contiguous bytes, your program's robustness is severely compromised, and the odds of elegant recovery are slim. |
#include <stdio.h> #include <stdlib.h> static void atexit_handler_1(void) { printf("within 'atexit_handler_1'\n"); } static void atexit_handler_2(void) { printf("within 'atexit_handler_2'\n"); } int main(void) { atexit(atexit_handler_1); atexit(atexit_handler_2); exit(EXIT_SUCCESS); printf("this line should never appear\n"); return 0; } /* When run yields within 'atexit_handler_2' within 'atexit_handler_1' and returns a success code to calling environment. */ (注意:如果你的程序在main函数结束时没有显式调用exit,那么你用atexit注册的处理函数也会被调用)。 abort与exit都不将控制权返回给调用者,并且结束程序。 条件结束 abort与exit无条件终止你的程序。你也可以有条件地结束你的程序,这种机制是每一个程序员喜受的诊断工具:assert宏定义在<assert.h>,如下示例: #if defined NDEBUG #define assert(condition) ((void) 0) #else #define assert(condition) _assert((condition), #condition, __FILE__, __LINE__) #endif //*******************************************************// (译注:assert的实现并不唯一,比如: Visual C++ 6.0的实现是: #define assert(exp) (void)((exp)||(_assert(#exp, __FILE__, __LINE__), 0)); Borland C++ 5.5的实现是: #define assert(exp) ((exp) ? (void)0 : _assert(#exp, __FILE__, __LINE__)) |
/* debug version */ #undef NDEBUG #include <assert.h> #include <stdio.h> int main(void) { int i = 0; assert(++i != 0); printf("i is %d\n", i); return 0; } /* 当运行后输出: i is 1 */ 那么现在改变代码版本到release版本,定义NDEBUG: /* release version */ #defing NDEBUG #include <assert.h> #include <stdio.h> int main(void) { int i = 0; assert(++i != 0); printf("i is %d\n", i); return 0; } /* 当运行后输出: i is 0 */ |
void _assert(int test, char const *test_image, char const *file, int line) { if (!test) { printf("Assertion failed: %s, file %s, line %d\n", test_image, file, line); abort(); } } |
/* 'f' never called by other programs */ static void f(int *p) { assert(p != NULL); /* ... */ } |
/* ...get file 'name' from user... */ FILE *file = fopen(name, mode); assert(file != NULL); /* 相当可疑的用法???questionable use */ |
By having two classes of return values, setjmp lets you determine how it's being used. When setting j, setjmp works as you normally expect; but as the target of a long jump, setjmp "wakes up" from outside its normal context. |
#include <setjmp.h> #include <stdio.h> jmp_buf j; void raise_exception(void) { printf("exception raised\n"); longjmp(j, 1); /* jump to exception handler */ printf("this line should never appear\n"); } int main(void) { if (setjmp(j) == 0) { printf("'setjmp' is initializing 'j'\n"); raise_exception();//Restore context printf("this line should never appear\n"); } else { printf("'setjmp' was just jumped into\n"); /* this code is the exception handler */ } return 0; } /* 运行结果: 'setjmp' is initializing 'j' exception raised 'setjmp' was just jumped into */ |
void f(void) { setjmp(j); } int main(void) { f(); longjmp(j, 1); /* 逻辑错误 */ return 0; } |
void handler(int signal_value); void f(void) { signal(SIGFPE, handler); /* 注册处理过程*/ /* ... */ raise(SIGFPE); /* 通过 'SIGFPE'来调用处理过程 */ } |
#include <errno.h> #include <math.h> #include <stdio.h> int main(void) { double x, y, result; /* ... somehow set 'x' and 'y' ... */ errno = 0; result = pow(x, y); if (errno == EDOM) printf("domain error on x/y pair\n"); else if (errno == ERANGE) printf("range error on result\n"); else printf("x to the y = %d\n", (int) result); return 0; } 说明:errno不需要引用到对象: int *_errno_function() { static int real_errno = 0; return &real_errno;//不需要这样做 } #define errno (*_errno_function()) int main(void) { errno = 0; /* ... */ if (errno == EDOM) /* ... */ } |
int f() { int error; /* ... */ if (error) /* Stage 1: error occurred */ return -1; /* Stage 2: generate exception object */ /* ... */ } int main(void) { if (f() != 0) /* Stage 3: detect exception */ { /* Stage 4: handle exception */ } /* Stage 5: recover */ } |
if ((p = malloc(n)) == NULL) /* ... */ if ((c = getchar()) == EOF) /* ... */ if ((ticks = clock()) < 0) /* ... */ |
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者