免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: wheniwasyoung
打印 上一主题 下一主题

C++写后台程序时,是否不提倡try...catch... [复制链接]

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
51 [报告]
发表于 2010-02-04 02:23 |只看该作者
本帖最后由 OwnWaterloo 于 2010-02-04 02:25 编辑

回复 50# 群雄逐鹿中原

你说中了, 还真就是宏。

从pthread_cleanup机制学到的……
pthread_cleanup机制对使用有一些限制。
ieee 1003

These functions may be implemented as macros. The application shall ensure that they appear as statements, and in pairs within the same lexical scope (that is, the pthread_cleanup_push() macro may be thought to expand to a token list whose first token is '{' with pthread_cleanup_pop() expanding to a token list whose last token is the corresponding '}' ).


而后面有一段提示就更明显了
RATIONALE
The restriction that the two routines that push and pop cancellation cleanup handlers, pthread_cleanup_push() and pthread_cleanup_pop(), have to appear in the same lexical scope allows for efficient macro or compiler implementations and efficient storage management. A sample implementation of these routines as macros might look like this:

#define pthread_cleanup_push(rtn,arg) { \
    struct _pthread_handler_rec __cleanup_handler, **__head; \
    __cleanup_handler.rtn = rtn; \
    __cleanup_handler.arg = arg; \
    (void) pthread_getspecific(_pthread_handler_key, &__head); \
    __cleanup_handler.next = *__head; \
    *__head = &__cleanup_handler;

#define pthread_cleanup_pop(ex) \
    *__head = __cleanup_handler.next; \
    if (ex) (*__cleanup_handler.rtn)(__cleanup_handler.arg); \
}


A more ambitious implementation of these routines might do even better by allowing the compiler to note that the cancellation cleanup handler is a constant and can be expanded inline.


这个限制主要是为cleanup_handler所需要的数据都可以在栈上分配, 然后用嵌入式链表将他们链成一个stack, 从而避免动态内存分配。
如果实现一个池, 只服务于LIFO的内存请求; 那用这种池的效率和栈也不会差太多了。 可能就可以取消这个限制, 而且,栈空间还是蛮宝贵的……


btw: 以前读最后一段的时觉得很疑惑……
没有发现通过这种函数指针(非参数)调用也可以inline的情况……
本来还想去找标准中有没有什么地方对函数指针调用函数有什么限制。
直到用了gcc4.4.0, 发现被inline了……

论坛徽章:
0
52 [报告]
发表于 2010-02-04 03:10 |只看该作者
楼上几(十)层楼的讨论
说明了try catch有多么重要....

如果C++标准里面有对try catch的实现有规定的话就好了

论坛徽章:
0
53 [报告]
发表于 2010-02-04 09:39 |只看该作者
setjmp()&longjmp()可以认为类似C++ exception处理形式. C程序, 有的情况下, 借助这两工具问题处理起来简单了很多.

论坛徽章:
0
54 [报告]
发表于 2010-02-04 09:49 |只看该作者
1. 增强程序健壮性,减少BUG
如果系统某个地方throw异常,程序员必须在某个地方catch它,然后进行处理:处理错误或重新throw。如果采用错误码来处理错误,错误的返回值可以被忽略,可能这个错误会导致系统的运行状态处于无定义状态,在某一时刻导致系统崩溃。
2. 错误处理集中化,使代码变得更简洁优美,更易维护
在某个地方throw异常,然后在某个地方catch。单从只有两层调用的简单代码层次上来说,我们可能认为,异常处理让代码变得更复杂了。但如果你的调用关系是多层的,异常的好处就体现出来了。这个实际开发中应该会有所体会。如果采用返回错误码的方式,你必须在每个调用处处理返回值,会增加许多的重复代码。
3. 错误信息更灵活、丰富
异常具有继承的物征。
--------------------
补充一下, 使用异常也会带来一些问题, 比如在某个层次抛出异常, 在抛异常后面一些关键代码逻辑没有执行到,会导致各种问题,常见的是资源泄漏之类的. 直接但丑陋的处理方法是在这个层次try...catch; 常用的推荐方法是引入智能指针或者一个辅助的当异常抛出异常时会自动处理善后工作的对象. 这个要做的工作确实多了一点,而且得小心地处理. 用错误返回码的方式,这类工作也是得做.

论坛徽章:
1
双子座
日期:2014-08-29 17:15:03
55 [报告]
发表于 2010-02-04 12:52 |只看该作者
就是他不从,然后就被玩死了
daybreakcx 发表于 2010-02-02 13:16


。。。。。

论坛徽章:
1
双子座
日期:2014-08-29 17:15:03
56 [报告]
发表于 2010-02-04 12:56 |只看该作者
class E{
public:
    E(){throw XXX;}
};

int main()
{
    E e;
    return 0;
}
aeeaaee 发表于 2010-02-03 09:50


这么明显的就不用摆上来了吧,哥们。  不带这样鄙视我的。

他说的基本类型的赋值

论坛徽章:
0
57 [报告]
发表于 2010-02-04 13:34 |只看该作者
当时是在review我们的代码,说为啥没有异常处理?  我说这段代码是最基本的运行代码,内部调用也不没有 ...
srdgame 发表于 2010-02-02 12:43



    确实很不理解,正常的赋值语句怎么会抛出异常?

    如果你用c库,这根本不可能吧。

    我觉得代码里面用try,catch是用一个复杂的方法替代另外一个复杂的方法。

    不用,有时候会觉得用返回值判断错误很不方便。用了,有时候又觉得很麻烦。

    而且需要注意的一点是,用try,catch,基本上需要结合智能指针来用,否则很容易内存泄漏。

论坛徽章:
0
58 [报告]
发表于 2010-02-04 14:08 |只看该作者
这个我会
后台函数中一般不写try catch,当有异常时,直接爆发异常就可以了,由函数调用者进行处理
如要写一个开平方函数,我会这么写
public double kpf(double v)
{
    if(v<0)
        throw new exception("数值不得小于0");
    ........
}
这种函数中起始就不用做异常处理,到哪失败,在哪停止就可以了.
但由用户激发的调用的地方需要做try处理,一般是点个按钮

public void buttonclick()
{
    try
    {
        ...;
        kpf(4);
        ...;
    }
    catch(Exception e)
    {
          MessageBox.show("发生了意外错误:"+e.toString());
    }
}

一般不用return 0,return 1之类的方法表示成功或失败,以前的开发语言没有错误处理机制,这样做,当函数被嵌套多层调用的时候,这么做非常不方便,函数执行失败的时候每个还得做单独的处理
但现在的开发语言都有错误处理机制,用上面的方法,即使很多层被嵌套调用,最深一层的爆发了错误,错误也能被逐级传递到调用者,而最终呈现给用户.

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
59 [报告]
发表于 2010-02-04 19:33 |只看该作者
杯具!这么看来我学不会C++了。
prolj 发表于 2010-02-02 12:48



小屁孩,不懂了吧~~

*((int *)0)=0 就会异常~~

或是
const int i=5;
i=6;也可能异常(有可能i被放在ReadOnly内存中)



不过,BS一下装B的说“基本Assign”也会异常的人。
这样程序还能写得出来么?

论坛徽章:
1
双子座
日期:2014-08-29 17:15:03
60 [报告]
发表于 2010-02-05 11:02 |只看该作者
确实很不理解,正常的赋值语句怎么会抛出异常?

    如果你用c库,这根本不可能吧。

    我 ...
yaoaiguo 发表于 2010-02-04 13:34


我从来也没有遇到过那种情况,这不过是某人自己说自己遇到过。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP