V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
huzhikuizainali
V2EX  ›  C++

关于"异常捕捉"(try catch)是否存在悖论?

  •  
  •   huzhikuizainali · 264 天前 · 829 次点击
    这是一个创建于 264 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我看了相关介绍和语法。C++ 用 try 去囊括可能出问题的代码。然后用 Catch 来提供潜在问题的处理方法。

    悖论在于:如果你意识到这段语句可能出问题,为什么不前置语句处理潜在隐患,从而使程序变得更健壮呢?

    例如,你担心这段程序可能出现除零问题,你就在这段代码前面作输入参数检测。如果这段代码要用打印机打印,你担心打印机没通电,没连接到电脑会引起程序崩溃。那么你在打印 语句之前,加上打印机状态检测语句。

    另一方面,如果你根本没有意识到这段代码可能出问题,那么你也不会给这段代码加上 try 语句,对吧。

    try catch 就像你发现水桶在漏水,但是你的方法是把漏的水接住,再倒回水桶。 可你已经发现水桶在漏水,为什么不把漏洞直接堵上呢?

    whileFalse
        1
    whileFalse  
       264 天前 via Android
    同理我也不理解为什么要设计 for 循环,明明使用 if goto 就可以解决问题
    pursuer
        2
    pursuer  
       264 天前
    try catch 从控制流上来说具有多级退出函数的作用。实现这个你也可以采用 if return ,只是 c++提供了这样的语法糖,性能可能也会好一点(这个未考证,考虑到栈恢复比逐级退出函数简单一点的结论)
    FreeWong
        3
    FreeWong  
       264 天前
    在 golang 和 rust 中,一个方法会不会出现异常或是错误,你看方法签名就知道了,直观吧,但是他们不使用 try catch.
    在 c#中,一个方法会不会出现异常要看方法的文档, 如果方法的源代码实际会出现一个异常,但是文档中却没有记录,然后你却没有使用 try catch 会怎样?

    再看从易于编程这个角度来看,tfy catch 或是 finally,你要牢记这里面的使用规则吧,要花篇幅向读者介绍如何使用吧,时间长了,你能全部都记牢?

    那么再比较 golang rust ,你就能体会到 不用花时间记这么多的规则 。同意吧
    clooooo
        4
    clooooo  
       264 天前
    您提出的问题确实很有见地,使用 try-catch 来处理可预见的错误状况,似乎不如提前做输入校验和状态检测来得直接有效。但是,try-catch 作为一种错误处理机制,仍有其适当的使用场景:

    1. 当某些错误状况难以完全避免时,try-catch 可以用来控制错误扩散范围,防止整个程序崩溃。比如外部系统异常、网络中断等不可控因素。

    2. 对于业务逻辑复杂的情况,想要全面预测并避免所有错误是很困难的。try-catch 可以用来处理意料之外的异常状况。

    3. try-catch 允许将错误处理与业务逻辑代码解耦,使主要逻辑更简洁清晰。合理使用也可以使程序结构更灵活。

    4. 对于一些开发者不可修改的第三方代码,try-catch 可能是处理潜在错误的最佳手段。

    所以,try-catch 更多是作为最后的“安全网”,并不是用来代替前置的输入校验和状态检测。合理的方法是状态检测与 try-catch 共同使用,使程序既健壮又能优雅地处理边界情况。总之,try-catch 并不是万金油,还需要开发者理性判断其适用场景。
    yanyao233
        5
    yanyao233  
       264 天前
    我最先能想到的就是网络连接问题,对于这种可以预料但不可控的问题,try catch 有必要
    huzhikuizainali
        6
    huzhikuizainali  
    OP
       264 天前
    @clooooo 谢谢你的详细的回复!
    ”1. 当某些错误状况难以完全避免时“ ------这是否可以理解为,我觉得这段代码不够健壮,可能会崩。但是它崩的可能情况过多。所以我前置的检测也许覆盖不到所有情况。因此用 try 来囊括它,让它无论怎么崩都能回到 catch 路径上去。我的理解正确么?

    “try-catch 允许将错误处理与业务逻辑代码解耦,使主要逻辑更简洁清晰。”-------意思是如果代码作者在一段可能会崩的代码前面加上一堆前置验证程序,别人阅读代码时未必会很快理解这段前置验证代码的作用。但是用 try catch 包装一下。代码的读者会更容易理解你是在写“防崩”代码。增加可读性。我理解的对么?
    think9999
        7
    think9999  
       264 天前
    try -catch 本来是设计为捕捉 硬件级别的问题。
    写过汇编的就会知道。
    但是,滥用后,比如自己都来抛出异常,try catch 就变成了所谓的系统性工程。
    实践时,肯定要自己来处理错误,这样代码的健壮性才强。
    一些不负责的程序员,什么都揉成一堆,反正不成功就重试,等等。屎山就是很多细节一点点堆出来的。
    shyrock
        8
    shyrock  
       264 天前
    说说我的理解:
    1.try catch 提供了一套独立于业务逻辑流的异常处理流,便于减少异常处理逻辑对业务逻辑的侵入,方便代码维护。
    2.try catch 面向异常(应该由系统级代码处理而不是业务级代码处理的问题)而不是业务逻辑错误。使用者应该严格遵守这个约定,非系统程序员不应该抛出自定义的异常来处理业务逻辑错误,而应该用函数返回逻辑来处理业务逻辑错误。
    3.其实大部分情况下,我会注册一个全局异常的处理器,而在业务代码中完全弃用异常处理,让系统自动上升异常到全局异常处理器来处理。
    4.对于系统通过异常机制防止系统错误扩散的情况,我会倾向于把异常可能性较大的代码(比如接收网络输入数据的模块)封装为独立的进程,再用全局异常处理器来处理。
    MiracleShadow
        9
    MiracleShadow  
       263 天前   ❤️ 1
    > What good can using exceptions do for me? The basic answer is: Using exceptions for error handling makes your code simpler, cleaner, and less likely to miss errors. But what’s wrong with “good old errno and if-statements”? The basic answer is: Using those, your error handling and your normal code are closely intertwined. That way, your code gets messy and it becomes hard to ensure that you have dealt with all errors (think “spaghetti code” or a “rat’s nest of tests”).


    https://isocpp.org/wiki/faq/exceptions#why-exceptions
    iceheart
        10
    iceheart  
       256 天前 via Android
    bug != 异常
    try throw catch 才是完整组合
    weeei
        11
    weeei  
       240 天前
    肯定存在当前逻辑不知道如何处理的错误/异常,抛出来给上层继续处理是合理的。
    至于你说的为啥为啥的情况,只能说是他们滥用了。
    tyzandhr
        12
    tyzandhr  
       216 天前 via Android
    对比 try catch 机制与另一种常见的错误处理机制,rust 中的 result ,fp 中的 maybe ,c++中的 optional 而言,前者是基于类型系统的错误处理,而后者是基于值的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   926 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 19:49 · PVG 03:49 · LAX 12:49 · JFK 15:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.