- 主题:大家都用C++的try catch吗?
码农还怕这个?码农的工作充满了各种选择和balance
c++的异常相比java、c#之类的异常难于普及,肯定是有原因的。
机翻一下28楼链接里的分析:
使用异常
另外一个处理错误的选择是显而易见的!就是使用异常。当然,如果你可以的话。它们并不在所有不同的环境中都允许使用,有些团队禁止使用它们。
在某种意义上,这是一个有争议的话题,因为人们对异常可能有非常坚定的看法,很多书籍和会议演讲都可以围绕异常来展开,也确实有很多这样做的。
有些人认为它们代价高昂。像往常一样,这取决于情况。如果你大部分时间都在从数据库读取数据或通过网络发送数据,那么这就没有那么重要了。
另一方面,始终为真的是,它完全绕过了正常的控制流程,使用异常的代码是非常难以推理的。通常你看不到,或者很难看到从你开始的地方结束在哪里。很多人误用异常,多次记录错误并且继续抛出异常。
我认为唯一能让它运行良好的方式是,如果你有一个明确陈述在文档中的异常处理策略。即便如此,也有很大的可能性会不被遵守。尤其是在大型公司中,员工总是变来变去。
【 在 chunhui 的大作中提到: 】
: 考虑什么情况下需要和不需要是一种负担。考虑错了,全白搭。
--
修改:z16166 FROM 222.128.162.*
FROM 222.128.162.*
erlang能fail fast,是因为它有轻量级进程,并且只通过消息通信,做了隔离
其他语言写的程序可能都不具备这个条件
【 在 chunhui 的大作中提到: 】
: 其实我没正经用过c++。不过我更喜欢erlang那种错了就及时挂的想法。
--
FROM 222.128.162.*
既不测试,也不反汇编分析,更不查资料,就这么怀疑,符合“人们对异常可能有非常坚定的看法”这个描述,只不过是无根据的"坚定",俗称“无脑顽固派”
【 在 lwp 的大作中提到: 】
: 不抛异常性能往下掉是你测试测出来的结论?
: :
--
FROM 222.128.162.*
跟ABI有关
MS针对x64规定了一套ABI,把异常处理的信息静态存储在64位PE文件的IMAGE_DIRECTORY_ENTRY_EXCEPTION这个位置的表里,里面有unwind chain。一般是编译器负责生成这个表。
发生异常时(比如调用RaiseException()这个OS API来抛出异常),OS可以根据这个表进行异常派发,然后可以调用和语言相关的异常处理程序,比如C++的__CxxFrameHandler3、__CxxFrameHandler4等。
自己手写汇编代码的话,只要遵循这个ABI,也是可以正常处理异常的。
JIT动态生成的代码的话,有对应的OS API RtlInstallFunctionTableCallback()/RtlAddFunctionTable()可以动态注册异常处理信息。
ARM32 ABI和32-bit x86差不多,都是用代码动态生成SEH链。
ARM64 ABI和x64差不多。
还有一个ARM64EC ABI,用于ARM64和x64的交互,win11 on arm用的。
【 在 hgoldfish 的大作中提到: 】
: 为啥 amd64 架构能做到这样。是 CPU 特别处理的吗?
: arm32 和 arm64 有没有这样的区别?
:
--
FROM 222.128.162.*
32位x86也可以按x64这么设计,不过因为32位ABI当时就那么定了,得用代码动态建立exception handler chain。
转一个比较:www dot osronline dot com /article.cfm%5earticle=469.htm
因为在 x86 上,每个使用 SEH 的函数都将上述结构作为其序言的一部分,所以据说 x86 使用基于帧的异常处理。这种方法有几个问题:
由于异常信息存储在堆栈上,因此很容易受到缓冲区溢出攻击。
高开销。异常就是异常,这意味着在常见情况下不会发生异常。无论如何,每次输入使用 SEH 的函数时,都会执行这些额外的指令。
由于 x64 是一个消除数十年来许多弊端的机会,SEH 进行了彻底改革,解决了上述两个问题。在 x64 上,SEH 已经变成基于表的,这意味着在编译源代码时,会创建一个表来完整描述模块内的所有异常处理代码。然后将该表存储为 PE 标头的一部分。如果发生异常,Windows将解析异常表以找到合适的异常处理程序来执行。由于异常处理信息安全地隐藏在 PE 标头中,因此它不再容易受到缓冲区溢出攻击。此外,由于异常表是作为编译过程的一部分生成的,因此在正常处理期间不会产生运行时开销(以push和pop指令的形式)。
当然,基于表的异常处理方案本身也有一些负面影响。例如,基于表的方案往往比基于堆栈的方案占用更多的内存空间。此外,虽然正常执行路径中的开销减少了,但处理异常所需的开销明显高于基于帧的方法。与生活中的一切一样,在评估基于表的异常处理方法还是基于帧的异常处理方法是否“最佳”时,需要考虑权衡。
【 在 hgoldfish 的大作中提到: 】
: 也就是说这个是 windows 针对 PE 格式的特殊规定。
: 32 位不支持纯粹只是因为 32 位 windows 不支持,而不是因为什么处理器的限制是吧?
:
--
FROM 222.128.162.*
windows没有risc-v平台的,所以没有risc-v的windows ABI
linux的你可以自己查一下资料和代码实现
【 在 chaobill 的大作中提到: 】
: risc-v arm 等平台呢,又怎么设计的
--
FROM 222.128.162.*
这不是个对错问题,而只是个flavor或者说paradigm问题。
根据自己的balance标准决定怎么搞。cpp大佬包括cpp他爹B.S,都是推荐用异常。
但要防止滥用异常,人多时这个并不一定好解决。
而且,为什么死盯着cpp的异常,认为它开销高、烂,而不认为java/c#/python/js等的异常开销高、烂呢?
【 在 overcomeunic 的大作中提到: 】
: 别整没用的
: 将一个string转换成int32,抛异常,你觉得是对 还是 不对
:
--
修改:z16166 FROM 222.128.162.*
FROM 222.128.162.*
你都没提供证据证明"C++异常肯定会影响性能",就武断下结论,属于“顽固派”的一种。
这就跟楼主顶楼里写的“C++异常会把调用栈搞没”一样属于无脑推测但又不验证分析的,不值得一驳。
为啥呢,因为张嘴就来很简单,但是要分析得下工夫、考验技术,所以无脑懒人都是规避后者的,毕竟上下嘴唇一张一合就能唾沫四溅地开喷,多爽啊
c++异常为啥没流行开,我之前转帖的那个机翻已经分析了好几条了
cpp大佬只是推荐用异常(具体文字我懒得贴,自己看去吧,不惯懒人了),又不是强制用异常,不用那么反感,好像反对大佬就表现得敢于挑战权威、很有独立思考的样子。独立思考靠的是拿事实摆证据详细分析,而不是“莫须有”。
而且这正是c++支持多范式、给码农充分自由度的最好佐证,搞不定的c++ feature就不要乱用,完全可以继续用返回码那套。
【 在 foliver 的大作中提到: 】
: 不要看BS怎么说,他是标准委员会的,会自己打自己脸?
: 坚决反对在C++使用异常。原因
: 1)性能,C++异常肯定会影响性能。看看C++异常生成的代码就知道了,说不影响性能那是自欺欺人。
: ...................
--
修改:z16166 FROM 222.128.162.*
FROM 222.128.162.*
看来你已经被cpp f**k得太多了,以至于辩不过要来这种方式了
【 在 overcomeunic 的大作中提到: 】
: 那还说啥呀
: 如果这么基础的一个函数 抛异常,你是用 还是 不用
: 那还是被FUCK得少了啊,FUCK多了嘴就不硬了
--
FROM 222.128.162.*
说出你的故事
【 在 overcomeunic 的大作中提到: 】
: 嗯,被干几次就老实了
: 多说无益,都是实践出真知,讲得再高大上,没卵用
--
FROM 222.128.162.*