- 主题:大家都用C++的try catch吗?
c++异常不好,那只是你的结论而已,居然被你说成了放之四海而皆准颠扑不破的真理了
无知又不学习,还死抱着自己的观点不放的,是什么人呢
游戏引擎在使用时有帧数要求,类似准实时系统。
对处理时间有要求的领域,是不适合用异常的,这个帖子的前面楼层已经有人问过,你没仔细看。
因为异常的处理时间无法做到固定,比如堆栈unwind时要查表几级、析构多少个对象是无法预知的。
还有个原因,一些成功的库或者框架,在最初开发时,C++的异常和其他标准都不成熟,不用异常,甚至不用STL都是可能的,不能说明什么问题。
【 在 foliver 的大作中提到: 】
: 上升到哲学高度了?c++异常就是不好,竟然还有人争论?
: 再说个c++最成功的一个领域,虚幻引擎都是默认禁用异常的。为啥?虚幻的设计师和开发人员都是很差?
:
--
修改:z16166 FROM 222.128.162.*
FROM 222.128.162.*
你试图用某几个项目没有使用异常,来证明异常不靠谱,这本身是个错误的推理。
因为按你这个推理,只有100%的项目都使用了异常,才能证明异常是靠谱的。
"unreal engine没使用异常,是因为游戏帧数有响应时间要求",这是我拍脑袋的分析。对错与否,可以继续辩。
实际上,性能问题是unreal关注的重点之一。它自己的编码规范写的:
"从历史上看,UE 避免直接使用 C 和 C++ 标准库。造成这种情况的原因有几个,包括:用我们自己的实现替换缓慢的实现,允许对内存分配进行额外的控制,在广泛可用之前添加新功能,进行理想但非标准的行为更改,在整个代码库中具有一致的语法,或者避免与 UE 的习惯用法不兼容的构造。然而,近年来,标准库变得更加稳定和成熟,并且包含了我们不想用抽象层包装或自己重新实现的功能。"
以上是unreal不使用某些C/C++特性的原因。在unreal早期开发时,C/C++的很多基础设施还不够好,包括跨平台的异常支持,但是一旦C/C++的标准实现比unreal自己撸的还要好时,它也是允许提出替换的,是开放的。
C++抛出异常时确实有开销,而且可能还不小,这个我也没否认,所以才会认为可能影响游戏帧数响应。
不光是反射,unreal还有GC,这是它自己的balance,牺牲一点性能换取其他好处。能支持脚本开发,就是为了享用脚本开发的便利性和扩展性。
【 在 foliver 的大作中提到: 】
: 为啥游戏不能用异常,虚幻自带了反射系统,这个消耗不大?你这是自相矛盾。
: 再给你一个LLVM的编码标准
: Do not use RTTI or Exceptions
: ...................
--
FROM 222.128.162.*
最基础的就是stl,
boost、opencv、jsoncpp、Poco、ChakraCore、facebook folly、 C++/WinRT、curlpp(libcurl的c++封装)、Apache MXNet、pybind11(被pytorch使用)、cppzmq(zmq的c++封装)、LibreOffice
【 在 foliver 的大作中提到: 】
: 那你就告诉我,那些项目使用了异常?
: 我好歹举例了,还是流行的。你也举个例子啊,让我学习学习
--
FROM 222.128.162.*
这个说法有点问题,
boost库的那些作者基本都是c++ expert,是用异常的,
推荐用异常的是几个c++ guru,
楼上一些嚷嚷c++异常开销大的,对现在编译器的try是近乎zero-cost反而不知道,只是凭感觉而罔顾事实,或者停留在以前的印象。
【 在 javaboy 的大作中提到: 】
: 其实绝大多数选用C++的人,追求的是zero-cost抽象:手上写的高等语法,脑子里盘算着这么写最后生成出来的机器语言会不会不完美。人家连用虚函数还是模板函数,都要纠结半天到底是要快几个cpu cycle还是省几个exe byte。
: C++的exception是违背这种zero-cost抽象的。try-catch的语法加上RAII,一不小心就能让
: catch部分本来就罗嗦的代码产生一堆副本,洁癖的人是受不了的。
: ...................
--
FROM 222.128.162.*
好多语言都能造原子弹,也能造茶叶蛋
茶叶蛋崩了是无所谓的,C++写的桌面GUI大多数情况下崩了也无所谓
【 在 fanci 的大作中提到: 】
: 怎么能用Java/Python/JS的标准要求C++呢?那些语言编写的程序压根儿都不需要错误处理,挂了重启是标准操作。
--
FROM 222.130.138.*
这个说法不准,是对实时性有要求的场合不适合用异常
用异常并不意味着降低可靠性
【 在 fanci 的大作中提到: 】
: 高可靠性的程序是不适合用异常的
: 异常主要用于业务逻辑,Python Java 那种,只需要在最外边 catch 一下记录下来然后退出。
--
FROM 222.130.138.*
有一个帖子,简单测了性能,包括expected<T>
帖子标题:Investigating the Performance Overhead of C++ Exceptions
MS编译器组的一个哥们2006年写了个仔细分析x86、x64异常的ppt:
The Cost of C++ Exception Handling on Windows — Kevin Frei
--
修改:z16166 FROM 222.130.138.*
FROM 222.130.138.*
刚搜到B.S自己2019年写了一个正式的为c++ exeption来argue的paper,P1947,title是C++ exceptions and alternatives
楼上有兴趣的可以批判一下里面的观点
--
FROM 222.130.138.*
单线程使用句柄,这种情况是没可能出现的
出现这种情况,通常是因为使用句柄时没保证MT-safe,也就是代码的逻辑bug。
这也是对try/catch的误用/滥用之一,用来掩盖代码的真实bug
MS在windows上更加激进,try/catch(...)可以设置为同时捕捉os异常和c++异常,极大地促进了catch(...)的滥用!
我现在看到catch(...)就反胃,对用这个的码农嗤之以鼻
这跟那些发现用FreeLibrary()来unload某些dll会崩或者卡死时,就不unload这个dll一样,顶多是个临时workaround。
还有个点是:
即便句柄没做到线程安全,线程A在用句柄时,句柄被线程B给close了,也不应该导致崩溃。这说明某个地方的处理代码没检查和这个句柄有关的API的返回值。
比如socket句柄,那是可以随便跨线程关闭的,线程A关闭这个句柄,并不会导致正在使用这个句柄的线程B、C、D崩溃,而只是导致线程B、C、D的send、recv操作失败返回而已。有的时候就是可以强行关闭socket句柄来让这些可能blocking的线程来退出的。
【 在 bn95 的大作中提到: 】
: 我以前不喜欢用,后来发现有时候是逃不掉的,不用程序会崩溃,特别是程序与外界有交互时
: 比如,如果你要操作一个windows句柄,可能出现这种情况
: 用if判断的时候,句柄是有效的
: ...................
--
修改:z16166 FROM 222.130.138.*
FROM 222.130.138.*
“c++启用异常后每层函数调用都要进行系统调用”这句完全错误。你好歹反汇编确认一下再发言啊。C++异常接受和使用程度没那么广,就是因为有这种无知但是"胆大"的人在误导。
虽然B.S喷了C++编译器的实现者这么多年来在C++异常的优化方面投入不足,但C++编译器的实现者也不是弱智,不至于弄一个"每层函数调用都要搞syscall"的低效实现机制。
rust没异常,不能说明有异常的语言就差
【 在 zli07 的大作中提到: 】
: 一句话秒了:rust 没有异常,只有 panic
: c++ exception 本质还是信号捕获,不像java只需要在函数头部声明一下try..catch的地址,c++启用异常后每层函数调用都要进行系统调用,完全得不偿失
:
--
修改:z16166 FROM 222.130.138.*
FROM 222.130.138.*