Monday, 14. January 2008, 06:05:40
programming, exception
1. 晦涩的多重出口
一个函数最好只有一个出口。但是有时为了减少函数代码的复杂度,也会在代码中间,比如一个判断之后使用return跳出函数。但是throw却和return不同,你无法的很快的判断throw之后的代码位置。你需要结合上下文,甚至是其他的函数来理解这一流程。你无法总是明确的知道一个throw会在什么时候被捕获。这是比goto更糟糕的东西!
虽然在happy path上你无需关注throw,但是却大大增加了调试的难度。而程序开发的大部分时间,都是在debugging而非coding。
2. 展开的堆栈有时无法跟踪
因为exception处理的存在,调试器中断后却不是停在原始的问题代码的地方,而是异常处理的代码中。常常出现在异常处理并不能有效的处理该异常的时候。而此时堆栈已经经过多次展开,无法回到问题代码处,导致调试的成本大大增加,甚至错误的把责任推给别人。
3. 不存在简单的异常处理代码
试图恢复一个异常,不如让他简单的crash。对大部分异常的恢复都是徒劳的,只不过是把原本应该你处理的东西丢给别人处理而已。如果仅仅只是想在函数的结尾集中处理,不如使用goto,简单而且高效。
而如果想真真处理异常,代码量是比较大的。虽然有的情况下这也是必须要做的事。这是我觉得异常还有一点用的地方。
4. 低下的效率
不管spec.上是怎么定义的,编译器在实现的时候都插入了不少代码来实现异常机制。而且,编译器比如vs2005对异常代码是没有优化的,这让情况变得更加糟糕。
至于进入ill path,堆栈展开的操作就可能耗费很多时间,因为所有的局部对象都需要析构。而此时,如果代码没有考虑到这一点,那么死锁或是其他更严重的问题也同时可能存在。
5. 增加设计难度
异常并非是out of the box的东西。真真要在程序中使用异常,需要经过周密的设计。仅仅try catch那是还没有入门的学徒。设计者要知道什么时候需要throw一个异常,throw一个什么类型的异常,这样的异常通常需要怎样的处理。调用者除了需要知道一个函数需要什么样的参数,返回什么值之外,还需要知道它会抛出什么样的异常!而此时,抛出的往往不是一个简单异常,而是一个异常类,i.e.,他们的复杂度是不一样的。
即使是经过这样的设计,异常也并非全然有效。程序还是会在某个不确定的时候crash。
更重要的是,类的设计者需要确信不在析构函数中调用会抛出异常的函数。
6. 给你稳定的假象
而更大的问题是,你以为程序是在正常的运行,其实它们却是在不停的抛出和处理异常。当你最终认识到这一点的时候,最佳的错误处理时机已经一去不复返了。这也是我之前所说的”不如让它crash“的原因。
7. 打破了代码设计的一些原则
C/C++中,{}定义了一个作用域。而try {} catch{}把一段代码分成了两个部分,try中的变量如果要在catch中进行判断,必须扩大它的作用域,此其一。
如果try中有多个条件或是循环,则条件或循环中的局部变量需要提出try,重名的需要改名,此其二。
throw增加了静态分析的难度,甚至令其变得不可能,i.e.破坏了代码的可读性,此其三。
以上并非是说不要使用异常处理,而是希望”不要随意使用异常处理“,
更不可用异常处理来替换错误处理(见1)。
Monday, 14. January 2008, 04:38:02
programming, exception
exception是有用的。但不能在程序中大量使用。更不能把exception作为error handling的一种方式。问为什么的人是还没有了解error和exception的区别。
就拿经典的除零来讲。大多数人都说除零是一个exception,但是忘了这是对cpu来说的。把零当成除数是一个常识性的错误(error),但对cpu来说只是一个异常,因为它并不了解一段机器码是一个除法,它没有除法单元。
但除零对大多数软件来说是一个错误,而非异常。因为一个变量没有判断是否为零就被当成了除数,这是一个明显的错误;除非并不了解它会被作为除数,那产生的可以说是一个异常。
还有一个例子,就是分配内存。使用异常来代替指针的判断,还说是提高可读性。这是对异常处理的极大误解。
程序中大量使用异常的,绝对不是为了提高程序的稳定性,或是可笑的可读性,那都是忽悠外行的。使用异常原因只有一个:偷懒!
老程序员使用异常,是不想写那么多的if判断,他们的catch中只有几行,并且通常都是catch(...);新程序员使用异常,是不知道该在哪个地方进行判断,而即使使用了异常机制,也不会写捕获代码,也通常只是catch(...)。
偷懒之外还有一种,是出于对异常的崇拜,他们的catch写得中规中矩,可惜用处不是很大,他们很快就会失去兴趣。
Thursday, 10. January 2008, 07:00:36
programming
The answer is
yes!
MOUSEEVENTF_LEFT* and MOUSEEVENTF_RIGHT* are all physical button of the mouse.
Here is a routine, the test codes for this case, from a mouse hook proc:
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0 || nCode == HC_NOREMOVE)
{
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
MOUSEHOOKSTRUCTEX *p_mhs = (MOUSEHOOKSTRUCTEX*)lParam;
switch (wParam)
{
case WM_LBUTTONDOWN:
{
mouse_event(MOUSEEVENTF_LEFTDOWN, LOWORD(lParam), HIWORD(lParam), 0, 0);
return 1;
}
break;
case WM_LBUTTONUP:
{
mouse_event(MOUSEEVENTF_LEFTUP, LOWORD(lParam), HIWORD(lParam), 0, 0);
return 1;
}
break;
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
Thursday, 20. December 2007, 09:30:40
Use following codes can create a "message transparent" window, all message will be sent to the window beneath it.
Tested in vista.
hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST/* | WS_EX_NOACTIVATE*/, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
SetLayeredWindowAttributes(hWnd, 0, 128, LWA_ALPHA);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
SetLayeredWindowAttributes is necessary, otherwise, the window with the ex_style WS_EX_TRANSPARENT will not display as a normal window.
But this method can not control the messages which can transparent send to beneath window and which canj not. Maybe a mouse hook can do the job.
Sunday, 2. December 2007, 02:26:01
ntfs
这是一个很老的话题了,但是好像很多人都有先入为主的偏见,觉得NTFS压缩需要经过压缩和解压缩的过程,会使整个系统变慢。
这种想法的根本原因,是由于哲学没有学好,世界观没有建立。在分析问题上,感到无能为力。只能人云亦云。
之所以这样讲,并非针对一般用户;而是很多程序员,都有这样的误区。
NTFS涉及到的主要的系统资源有三个方面:硬盘、内存和CPU。
NTFS的一大优点,世人都知道,是压缩文件。很多人的一个观点是,现在硬盘很便宜了,犯不着为了硬盘空间牺牲性能。这种想法的人,脑袋肯定被踢过——要是硬盘空间真的已经足够,何必再研发提高单碟容量?但是即便是很便宜,一个80G的硬盘还是要几百块钱,而且,电脑上未必有空间给你装。难道让大家不停的把80G的换成160G,160G不够用再换成320G的,在现在这种高清电影和游戏都快速膨胀的时代?
无节制、无管理,给再多资源也是浪费。
都说NTFS压缩消耗资源,消耗的是什么资源?
压缩、解压缩,都是数学运算,消耗的只能是内存和CPU的资源。而NTFS的压缩算法,并非很极端的压缩,往往它压缩过的文件,使用winrar还可以压缩30%。它的压缩、解压缩,对内存和CPU的消耗是很少的(google一下,就可以得到NTFS压缩的资料)。有那么多买硬盘的钱,不如投资到内存和CPU上,性能的提升,是全方面的。
而且,在当今标配的CPU和内存下,NTFS压缩并非仅仅只是减少空间使用这么简单。又要说到硬盘。硬盘的缺点是什么?速度!读取1G和读取0.5G哪个时间少?经过NTFS的压缩,往往可以达到50%的压缩率。现在PC的性能瓶颈,不是内存,也不是CPU,而是硬盘IO——它,实在是太慢了!使用一点内存和CPU的资源,而减少硬盘IO的次数,何乐而不为?
Friday, 23. November 2007, 15:13:48
今天从公司离职了。
工作6年以来,换了三家公司,辞了两次职,因为中间有一次是原公司被收购了,所以只能算是transfer。
还记得第一次离开工作了三年的公司的时候,走在回家的路上,非常的伤感,非常非常的放不下。
现在好像没有什么特别的感觉了。走得匆忙,竟然连离职证明都忘了拿了。
接下来,准备去杭州了。
Wednesday, 21. November 2007, 04:37:48
emacs
Failed to upload the .emacs or emacs files in 'Files' page directly, I upload the file here as a backup.
emacs
Tuesday, 20. November 2007, 08:22:36
.net framework
今天从msdn上抓了visual studio 2008下来开始安装,结果第一步安装.net framework 3.5就遇到了问题。
分析log后发现,说.net framework 2.0a没有安装。
我确实没有安装.net framework 2.0a。我装了1.0, 1.1, 2.0, 3.0,但是我找遍微软网站,也没有发现有一个package叫做.net framework 2.0a的。
除了“bull shit"之外,还能对微软说什么?
最后还是删了.net framework 2.0,重装才可以。
而删.net framework,还不能在Add-Remove中直接删除,需要用"install clean up"——微软出品——删掉.net framework 2.0的信息,才可以重装。
Thursday, 15. November 2007, 03:31:06
visual style
windows xp,之前一直用watercolor的vs没有问题。后来换了t61,分辨率升高到1920×1200,突然发现窗口的上边框无法上下拖动了。这问题困扰了我很久,直到今天……
我仔细观察了title bar,总觉得右上角的几个按钮相对太大了。之前也有发现,但一直是把title bar的size调大;今天突然想到,应该是调小才对。于是调到最小, 19,真的OK了。
后来换了字体,最小size又变了,不得不把字体的size调小,以适应title bar的最小要求。
Wednesday, 14. November 2007, 02:11:45
software
Type And Run是一个非常小巧但实用的软件,可以通过命令而非鼠标点击的方式启动程序。
之前使用tor的时候,需要启动vidalia, privoxy, mproxy,研究了一下,发现如果把三个程序的别名设置成一样,比如torpackage,这样输入torpackage之后,三个程序就一起启动了。
还是一个不错的应用。
Showing posts 21 -
30 of 241.