吉林-小伙 0:51:57
算了 不瞎扯了
吉林-小伙 0:51:58
呵呵
吉林-小伙 0:52:11
我慢慢学吧
深圳-Enic<errorcpp@qq.com> 0:52:09
这样就异常了
深圳-Enic<errorcpp@qq.com> 0:52:17
偶来看看啥异常
吉林-小伙 0:52:29
内存不够了
吉林-小伙 0:52:27
你这是new太多了
吉林-小伙 0:53:02
异常是 outofmemory
吉林-小伙 0:53:06
深圳-Enic<errorcpp@qq.com> 0:53:07
应该不是
深圳-Enic<errorcpp@qq.com> 0:54:21
被你说中了
深圳-Enic<errorcpp@qq.com> 0:54:27
bad allocation
吉林-小伙 0:54:39
呵呵
吉林-小伙 0:54:53
这样看来
吉林-小伙 0:54:57
只要内存够用
深圳-Enic<errorcpp@qq.com> 0:54:57
最近发现异常比返回值好用多了
深圳-Enic<errorcpp@qq.com> 0:55:10
mutex数量,这个问题我以后不应该纠结了
吉林-小伙 0:55:17
就能申请好多
深圳-Enic<errorcpp@qq.com> 0:55:24
说到底就是一条汇编指令
深圳-Enic<errorcpp@qq.com> 0:55:47
操作系统会缓冲下 id啥的
深圳-Enic<errorcpp@qq.com> 0:56:19
昨天一个多线程的代码,用了三方线程库,线程中不敢直接调用exitthread
吉林-小伙 0:56:35
怕内存泄露?
深圳-Enic<errorcpp@qq.com> 0:56:44
结果一个错误先直接退出线程,连续改了几层函数
深圳-Enic<errorcpp@qq.com> 0:56:51
void改成bool
深圳-Enic<errorcpp@qq.com> 0:57:09
后来 直接throw 一下
深圳-Enic<errorcpp@qq.com> 0:57:19
线程主函数catch一下
深圳-Enic<errorcpp@qq.com> 0:57:28
nnd 多简洁啊
吉林-小伙 0:57:38
异常处理影响效率啊
深圳-Enic<errorcpp@qq.com> 0:57:51
比每个函数后面跟一个assert 一个if舒服多了
吉林-小伙 0:58:04
呵呵
深圳-Enic<errorcpp@qq.com> 0:58:12
对了
吉林-小伙 0:58:09
泡泡鱼告诉我
吉林-小伙 0:58:21
你用异常处理 那是你代码写的有问题
吉林-小伙 0:58:31
正常情况下不用try catch
深圳-Enic<errorcpp@qq.com> 0:58:36
异常处理不影响正常流程的效率吧
吉林-小伙 0:58:53
影响
深圳-Enic<errorcpp@qq.com> 0:58:55
那确实是有问题,发现一个不可恢复的错误
深圳-Enic<errorcpp@qq.com> 0:59:17
要么直接退出
深圳-Enic<errorcpp@qq.com> 0:59:23
要么泡异常
深圳-Enic<errorcpp@qq.com> 0:59:39
囧,,,
boost的正则
深圳-Enic<errorcpp@qq.com> 0:59:46
这么说来就是狗屎了
吉林-小伙 0:59:50
more effective c++ 里好像说了异常处理的效率问题了
深圳-Enic<errorcpp@qq.com> 0:59:56
到处异常,基本不靠返回值
深圳-Enic<errorcpp@qq.com> 1:00:02
我看看汇编代码
吉林-小伙 1:00:07
嗯
吉林-小伙 1:00:15
想想异常处理的原理
深圳-Enic<errorcpp@qq.com> 1:00:24
我觉得没啥
深圳-Enic<errorcpp@qq.com> 1:00:31
编译器完全可以处理吧
吉林-小伙 1:01:12
你看看汇编代码
吉林-小伙 1:02:27
经测试,在C++里面加个try以后性能下降了百多倍
深圳-Enic<errorcpp@qq.com> 1:02:33
多了几个jmp
深圳-Enic<errorcpp@qq.com> 1:02:42
你测过了?
吉林-小伙 1:03:09
你用for 然后里边写个try catch
吉林-小伙 1:04:13
我觉得一定会低效的
吉林-小伙 1:05:20
因为为了捕捉到异常以后
吉林-小伙 1:05:24
仍然能堆栈平衡
深圳-Enic<errorcpp@qq.com> 1:05:28
try
{
00EC2390 mov byte ptr [ebp-4],1
int i = 0;
00EC2394 mov dword ptr [i],0
}
00EC239B jmp __catch$_wmain$0+14h (0EC23B1h)
catch(...)
{
int i = 0;
00EC239D mov dword ptr [i],0
}
00EC23A4 mov dword ptr [ebp-4],0
00EC23AB mov eax,offset __tryend$_wmain$1 (0EC23B8h)
00EC23B0 ret
00EC23B1 mov dword ptr [ebp-4],0
}
00EC23B8 jmp wmain+51h (0EC2381h)
00EC23BA jmp __catch$_wmain$4+38h (0EC24C3h)
吉林-小伙 1:05:30
正常结束程序
吉林-小伙 1:05:40
就必须要加入一些数据结构
深圳-Enic<errorcpp@qq.com> 1:05:42
是一个长jmp
深圳-Enic<errorcpp@qq.com> 1:05:50
编译器干的
吉林-小伙 1:05:59
对啊
深圳-Enic<errorcpp@qq.com> 1:06:13
如果没有异常,直接jmp到后面了
深圳-Enic<errorcpp@qq.com> 1:06:23
就多了这一条指令
吉林-小伙 1:06:33
你看的是表面
吉林-小伙 1:06:39
jmp之后呢?
吉林-小伙 1:06:54
正常 stdcall的函数 是在函数内部堆栈平衡的
深圳-Enic<errorcpp@qq.com> 1:07:01
之后是后面正常的代码
吉林-小伙 1:07:02
这个你不否认吧
深圳-Enic<errorcpp@qq.com> 1:07:07
jmp没有call吧
吉林-小伙 1:07:21
你先别看那个汇编
吉林-小伙 1:07:25
听我说
吉林-小伙 1:07:26
呵呵
深圳-Enic<errorcpp@qq.com> 1:07:29
恩
吉林-小伙 1:07:37
正常我们调用一个函数
吉林-小伙 1:07:50
是stdcall 这个函数执行完毕的时候
吉林-小伙 1:08:02
要堆栈平衡一下 例如ret 8
吉林-小伙 1:08:33
这样才能保证函数退出后依然能正确执行代码
吉林-小伙 1:08:43
如果我们的函数中存在异常
吉林-小伙 1:08:58
就执行不到ret 8了
深圳-Enic<errorcpp@qq.com> 1:09:13
我说的是正常流程
吉林-小伙 1:09:23
哦
吉林-小伙 1:09:28
懂你的意思了
深圳-Enic<errorcpp@qq.com> 1:09:50
我用异常是难得一层一层加返回值判断了
吉林-小伙 1:09:48
不管是什么流程
吉林-小伙 1:10:20
是不是要先弄个数据结构来保存下一些信息呢?
深圳-Enic<errorcpp@qq.com> 1:10:32
就是throw的
深圳-Enic<errorcpp@qq.com> 1:10:44
throw就是一个call了 好像
深圳-Enic<errorcpp@qq.com> 1:10:48
我去看看
吉林-小伙 1:10:50
嗯
深圳-Enic<errorcpp@qq.com> 1:12:11
throw(i);
002C237B mov eax,dword ptr [i]
002C237E mov dword ptr [ebp-148h],eax
002C2384 push offset __TI1H (2D8540h)
002C2389 lea ecx,[ebp-148h]
002C238F push ecx
002C2390 call @ILT+1225(__CxxThrowException@8) (2C14CEh)
深圳-Enic<errorcpp@qq.com> 1:12:15
就是了
吉林-小伙 1:12:24
嗯
深圳-Enic<errorcpp@qq.com> 1:13:02
囧,,,
深圳-Enic<errorcpp@qq.com> 1:13:07
汇编果然是好东西
深圳-Enic<errorcpp@qq.com> 1:13:55
看了评测
深圳-Enic<errorcpp@qq.com> 1:14:14
win上的异常要损失130倍
吉林-小伙 1:14:14
什么评测?
深圳-Enic<errorcpp@qq.com> 1:14:16
性能
深圳-Enic<errorcpp@qq.com> 1:14:24
异常发生
吉林-小伙 1:14:38
不发生呢?
深圳-Enic<errorcpp@qq.com> 1:14:46
1%
吉林-小伙 1:14:50
不发生就多点内存?
深圳-Enic<errorcpp@qq.com> 1:14:51
Linux是0
吉林-小伙 1:14:57
那就不错了
深圳-Enic<errorcpp@qq.com> 1:15:00
aix比不用还要快一点
深圳-Enic<errorcpp@qq.com> 1:15:02
囧
深圳-Enic<errorcpp@qq.com> 1:15:37
应该是运行库觉得的
深圳-Enic<errorcpp@qq.com> 1:15:44
这个玩深了
深圳-Enic<errorcpp@qq.com> 1:15:49
艹,搞不定了
吉林-小伙 1:16:05
我给你翻翻权威书籍吧
吉林-小伙 1:16:07
哈哈
吉林-小伙 1:16:45
擦 今天书翻不了了
吉林-小伙 1:16:49
让隔壁的人拿走了
吉林-小伙 1:16:59
more effective c++
吉林-小伙 1:17:07
这里专门讲了异常
深圳-Enic<errorcpp@qq.com> 1:17:09
http://blog.codingnow.com/2005/12/cpp_exception.html
深圳-Enic<errorcpp@qq.com> 1:17:35
我有印象那书
深圳-Enic<errorcpp@qq.com> 1:17:55
但是在汇编面前是没有秘密的,,,囧,,,明天好好分析下
深圳-Enic<errorcpp@qq.com> 1:18:16
当时讲师前半段一直在讲 SEH ,和 C++ 关系不大。我本以为会讲 C++ 异常的实现的,我个人以前研究过一些,很有兴趣听听人家的理解,结果没有听到。据说后来那个会场最终吵了起来,很遗憾没有领略那个盛况 :)
吉林-小伙 1:19:45
呵呵
深圳-Enic<errorcpp@qq.com> 1:21:01
程序中大量使用异常的,绝对不是为了提高程序的稳定性,或是可笑的提高可读性,那都是忽悠外行的。使用异常原因只有一个:偷懒!
深圳-Enic<errorcpp@qq.com> 1:21:08
深表赞同,,,
深圳-Enic<errorcpp@qq.com> 1:21:14
想少些代码
吉林-小伙 1:21:19
呵呵
吉林-小伙 1:21:29
泡泡鱼是个高手啊
吉林-小伙 1:21:34
可惜啊
吉林-小伙 1:21:41
这小子总是丢一句就跑
吉林-小伙 1:22:48
按道理来讲c++ happy path的时候 应该效率高的啊
吉林-小伙 1:22:56
毕竟不用返回值判断了
深圳-Enic<errorcpp@qq.com> 1:23:10
看异常实现了
深圳-Enic<errorcpp@qq.com> 1:23:25
这个是运行期间的事件
吉林-小伙 1:23:30
嗯
深圳-Enic<errorcpp@qq.com> 1:23:43
throw一下要去找catch
深圳-Enic<errorcpp@qq.com> 1:23:47
估计时间就在这里
吉林-小伙 1:24:03
这个是 unhappy了
深圳-Enic<errorcpp@qq.com> 1:24:05
我刚刚的例子是给编译器优化掉了
深圳-Enic<errorcpp@qq.com> 1:24:13
直接call了
吉林-小伙 1:24:13
unhappy path
吉林-小伙 1:24:15
哦 哦
深圳-Enic<errorcpp@qq.com> 1:24:21
这样应该是0开销
吉林-小伙 1:24:27
用g++吧
深圳-Enic<errorcpp@qq.com> 1:24:47
vs用的顺手额
吉林-小伙 1:24:51
看看不优化是什么样的
吉林-小伙 1:25:11
vs关闭优化功能
深圳-Enic<errorcpp@qq.com> 1:25:13
应该是和ssh那一套差不多
吉林-小伙 1:25:15
我心里还是不踏实呢
深圳-Enic<errorcpp@qq.com> 1:25:33
@ILT+1225(__CxxThrowException@8) (2C14CEh)
深圳-Enic<errorcpp@qq.com> 1:25:38
又看了下
深圳-Enic<errorcpp@qq.com> 1:25:42
call的是这个
吉林-小伙 1:26:02
传了两个参数
深圳-Enic<errorcpp@qq.com> 1:26:09
你拿od调看看
吉林-小伙 1:26:17
我没OD了
吉林-小伙 1:26:19
公司电脑
深圳-Enic<errorcpp@qq.com> 1:26:27
搞驱动的,,,
深圳-Enic<errorcpp@qq.com> 1:26:32
没OD?
吉林-小伙 1:26:43
没有啊
吉林-小伙 1:26:53
我现在只会简单的windbg
吉林-小伙 1:27:00
还是双机调试
吉林-小伙 1:27:19
OD能调内核程序?
深圳-Enic<errorcpp@qq.com> 1:27:43
那你用wdbg看看,,,
深圳-Enic<errorcpp@qq.com> 1:27:51
囧,,,我这些太弱了
吉林-小伙 1:28:15
你弄弄
吉林-小伙 1:28:24
我研究虚拟摄像头呢
吉林-小伙 1:28:28
我今天晚上要弄成功共
深圳-Enic<errorcpp@qq.com> 1:29:37
恩,祝你成功
我跟了一大段汇编
吉林-小伙 1:30:11
深圳-Enic<errorcpp@qq.com> 1:31:54
我决定以后还是不排斥异常
吉林-小伙 1:32:36
看你对代码体积 还有效率有没有什么特殊要求了
吉林-小伙 1:32:43
这东西 存在就合理
吉林-小伙 1:32:51
必有其用武之地啊
深圳-Enic<errorcpp@qq.com> 1:33:03
实在是少些太多代码的,,,
吉林-小伙 1:33:20
呵呵
深圳-Enic<errorcpp@qq.com> 1:33:23
你不知道,今天我改第一个函数 最少改了5层
吉林-小伙 1:33:30
不用返回值 不用断言和if
深圳-Enic<errorcpp@qq.com> 1:33:49
asio做的比较好
深圳-Enic<errorcpp@qq.com> 1:34:10
一个功能提供一个异常版和一个返回值版
深圳-Enic<errorcpp@qq.com> 1:35:00
http://www.cnblogs.com/napoleon_liu/archive/2010/10/27/1862240.html
深圳-Enic<errorcpp@qq.com> 1:35:12
这个是分析异常实现机制的
深圳-Enic<errorcpp@qq.com> 1:35:18
你可以明目了
吉林-小伙 1:35:35
不过记不太清了
吉林-小伙 1:35:32
以前看过
吉林-小伙 1:35:44
好像是和调用堆栈有关系
吉林-小伙 1:35:50
平衡堆栈那些
深圳-Enic<errorcpp@qq.com> 1:36:08
这些开销不会超过一倍的
深圳-Enic<errorcpp@qq.com> 1:36:44
就算不是异常平衡,你自己写返回值一样还是一层一层平衡下去了
吉林-小伙 1:37:13
嗯 但是用异常不是需要新的数据结构吗
吉林-小伙 1:37:17
这多了一些开销
吉林-小伙 1:37:51
现在我的水平 还不是纠结是否应该用异常的时候
吉林-小伙 1:37:51
呵呵
吉林-小伙 1:38:02
知道个大概就行啦 慢慢来吧
深圳-Enic<errorcpp@qq.com> 1:38:45
囧,,,
都是被逼的,,,
深圳-Enic<errorcpp@qq.com> 1:39:07
经过今天的事情,我才知道为啥要抛异常
深圳-Enic<errorcpp@qq.com> 1:39:38
你看超大型项目,好几百层的函数调用,,,
吉林-小伙 1:39:38
知道今天 你才知道抛出异常是call?
深圳-Enic<errorcpp@qq.com> 1:39:42
艹
深圳-Enic<errorcpp@qq.com> 1:39:48
那直接死了算了
吉林-小伙 1:40:32
你知道抛出异常的那个参数是干啥的不?
深圳-Enic<errorcpp@qq.com> 1:40:35
让你在第999层的函数调用根据一个返回值退出程序
深圳-Enic<errorcpp@qq.com> 1:40:40
不知道
深圳-Enic<errorcpp@qq.com> 1:40:51
结果上面998层都是void
吉林-小伙 1:40:57
呵呵
深圳-Enic<errorcpp@qq.com> 1:41:00
吉林-小伙 1:41:04
你说的也有道理
吉林-小伙 1:41:15
这个就是架构师设计的不合理了
吉林-小伙 1:41:35
throw 那个参数 可以传给catch那里
深圳-Enic<errorcpp@qq.com> 1:41:49
压了两个参数
深圳-Enic<errorcpp@qq.com> 1:41:53
还有一个是啥
吉林-小伙 1:42:02
你刚才写的是1吧
吉林-小伙 1:42:17
你写两个
吉林-小伙 1:42:21
看看是不是压了三个
深圳-Enic<errorcpp@qq.com> 1:43:28
你们家异常能一次throw俩参数
吉林-小伙 1:43:37
push offset __TI1H (2D8540h)
吉林-小伙 1:43:57
艹
吉林-小伙 1:44:11
从来没用过两个参数
吉林-小伙 1:44:14
不知道是否可以
吉林-小伙 1:44:25
压入了一个首地址
吉林-小伙 1:44:32
TI1H的首地址
深圳-Enic<errorcpp@qq.com> 1:44:39
还有一个后来跟汇编的时候好像看了啥info
吉林-小伙 1:44:48
这个TI1H是什么东东呢
深圳-Enic<errorcpp@qq.com> 1:45:08
我也不知道,估计是index之类的
深圳-Enic<errorcpp@qq.com> 1:45:17
要去找catch的
吉林-小伙 1:45:23
嗯
深圳-Enic<errorcpp@qq.com> 1:45:50
吉林-小伙 1:45:55
谢谢
吉林-小伙 1:46:04
今天对异常又有了新的理解啊
深圳-Enic<errorcpp@qq.com> 1:46:19
谢谢
吉林-小伙 1:46:24
这throw了一个对象
吉林-小伙 1:46:38
catch 那边就用的对象了
深圳-Enic<errorcpp@qq.com> 1:46:48
我今天最大的收获是在云风的博客,看到了异常的本质
深圳-Enic<errorcpp@qq.com> 1:46:51
偷懒,,,
深圳-Enic<errorcpp@qq.com> 1:47:04
和面向对象一样,,,
深圳-Enic<errorcpp@qq.com> 1:47:11
整个泥马就是想偷懒了
深圳-Enic<errorcpp@qq.com> 1:47:14
囧,,,
吉林-小伙 1:47:55
抛出异常这边用引用也白费吧
吉林-小伙 1:48:07
catch用引用也没用
吉林-小伙 1:48:12
还是copy了一份
深圳-Enic<errorcpp@qq.com> 1:48:31
这是看编译器操作了
吉林-小伙 1:48:39
不用看
吉林-小伙 1:48:43
必须copy
吉林-小伙 1:49:14
throw 那个地方是临时对象
深圳-Enic<errorcpp@qq.com> 1:49:16
那个程序实施看就知道了
深圳-Enic<errorcpp@qq.com> 1:49:27
不一定是临时的
吉林-小伙 1:49:32
一定的
吉林-小伙 1:49:34
呵呵
吉林-小伙 1:49:33
你试试
吉林-小伙 1:49:41
这个地方我记得最清楚
深圳-Enic<errorcpp@qq.com> 1:49:53
囧,我要是一个 关闭拷贝构造的class
深圳-Enic<errorcpp@qq.com> 1:49:57
你咋整,,,
深圳-Enic<errorcpp@qq.com> 1:50:04
不让抛了,,,
吉林-小伙 1:50:34
你试试
吉林-小伙 1:50:37
这个问题我真没想过
吉林-小伙 1:51:01
不过你怎么关闭拷贝构造呢?
吉林-小伙 1:51:39
默认构造你可以关闭
深圳-Enic<errorcpp@qq.com> 1:51:56
囧,,,
深圳-Enic<errorcpp@qq.com> 1:52:01
如果你说的成立
深圳-Enic<errorcpp@qq.com> 1:52:13
就是说这样违反了Cpp的语法规则
吉林-小伙 1:52:29
你打印下地址
吉林-小伙 1:52:34
看看 这个不是我说的
深圳-Enic<errorcpp@qq.com> 1:52:36
用 引用接收到一个 copy的对象
吉林-小伙 1:52:40
是我从书上看的
吉林-小伙 1:52:52
当然 不排除我记错的可能
吉林-小伙 1:52:58
但是 我觉得我没记错
吉林-小伙 1:52:59
呵呵
吉林-小伙 1:53:19
你试试 我去写摄像头
吉林-小伙 1:53:27
等你结果
深圳-Enic<errorcpp@qq.com> 1:56:13
囧,,,
是临时对象
吉林-小伙 1:56:24
深圳-Enic<errorcpp@qq.com> 1:56:25
所以,这里不是 call
吉林-小伙 1:56:36
引用失效了吧
深圳-Enic<errorcpp@qq.com> 1:56:39
应该有个运行时环境做了手脚
越南-relilun(232359027) 1:57:23
吉林-小伙 1:58:07
好了 既然已经确定是临时对象了 你告诉我下怎么关闭拷贝构造
深圳-Enic<errorcpp@qq.com> 1:59:29
囧,,,
深圳-Enic<errorcpp@qq.com> 1:59:35
private
深圳-Enic<errorcpp@qq.com> 1:59:45
class CTest : boost::noncopyable
吉林-小伙 1:59:49
深圳-Enic<errorcpp@qq.com> 1:59:52
还有一个是宏的,,,
吉林-小伙 1:59:56
我二了
吉林-小伙 2:00:00
你试试
吉林-小伙 2:00:04
试试
吉林-小伙 2:00:03
你关闭下十四行
吉林-小伙 2:00:13
看看让抛出不了
深圳-Enic<errorcpp@qq.com> 2:01:32
编译错误
吉林-小伙 2:01:53
嗯
吉林-小伙 2:01:56
太感谢了
深圳-Enic<errorcpp@qq.com> 2:01:56
刚刚是建立在假象throw和catch是直接call的关系
吉林-小伙 2:02:03
又学到了不少
深圳-Enic<errorcpp@qq.com> 2:02:38
应该是有个第三方 接收throw的对象,然后清理现场,然后拷贝异常,再送到 catch
吉林-小伙 2:03:06
如果你throw的不是对象呢
吉林-小伙 2:03:22
仅仅是一个char*
深圳-Enic<errorcpp@qq.com> 2:03:25
我想这不是问题
吉林-小伙 2:04:09
应该是采用同样的基址
深圳-Enic<errorcpp@qq.com> 2:04:09
今天的专题是:小伙和他的异常
吉林-小伙 2:04:11
机制
吉林-小伙 2:04:26
吉林-小伙 2:04:30
你可别发我
吉林-小伙 2:04:32
丢人
深圳-Enic<errorcpp@qq.com> 2:05:21
《一个异常引发的血案》
深圳-Enic<errorcpp@qq.com> 2:06:08
应该是mutex的数量到深入探讨C++异常
深圳-Enic<errorcpp@qq.com> 2:09:34
忘了说了
catch不用reference
会多一次拷贝
吉林-小伙 (694129464) 2:10:20
哦?
、
那更有意思了
哈哈
了解了
吉林-小伙 (694129464) 2:11:17
这时候就copy了一下
然后第三方传给 catch
深圳-Enic<errorcpp@qq.com> 2:12:37
三次析构
两次构造
有一次应该是 0x语法中的move
吉林-小伙 (694129464) 2:13:07
没用引用?
还是用了引用?
深圳-Enic<errorcpp@qq.com> 2:13:15
throw的时候
值catch
吉林-小伙 (694129464) 2:13:49
不应该三次析构 两次构造的啊
深圳-Enic<errorcpp@qq.com> 2:14:17
C++果然是不是一般人玩的
我这是算了 try里边的栈
c++太可怕了
深圳-Enic<errorcpp@qq.com> 2:15:50
话说java c#更可怕
你压根就不想知道编译器干了啥,,,
c++太可怕了
深圳-Enic<errorcpp@qq.com> 2:15:50
话说java c#更可怕
你压根就不想知道编译器干了啥,,,