来一发C言语中史上最愚昧的Bug
要明白学好linux不是一件一蹴而就的事,一定要能坚持使用它,特别是在使用初期。本文来自“ThemoststupidCbugever”,很成心思,分享给人人。我信任如许的bug,就算你是妙手你也会犯的。你来看看做者犯的这个Bug吧。。
起首,作者想用一段程序来创立一个文件,假如有文件名的话,就创立真实的文件,假如没有的话,就挪用?tmpfile()?创立一时文件。他这段程序就是HTTP下载的C程序。code==200就是HTTP的前往码。
elseif(code==200){//Downloadingwholefile/*Writenewfile(plusallowreadingoncewefinish)*/g=fname?fopen(fname,"w+"):tmpfile();}可是这个程序,只能在Unix/Linux下事情,由于Microsoft的?tmpfile()的完成?竟然选择了C:作为一时文件的寄存目次,这关于那些没有办理员权限的人来讲就出年夜成绩了,在Windows7下,就算你有办理员权限也会有成绩。以是,下面的程序在Windows平台下必要用分歧的体例来处置,不克不及间接利用Windows的tmpfile()函数。
因而作者就先把这个成绩记上去,在正文中写下了FIXME:
elseif(code==200){//Downloadingwholefile/*Writenewfile(plusallowreadingoncewefinish)*///FIXMEWin32nativeversionfailsherebecause//Microsoftsversionoftmpfile()createsthefileinC:g=fname?fopen(fname,"w+"):tmpfile();}然后,作者以为必要写一个跨平台的编译:
FILE*tmpfile(void){#ifndef_WIN32returntmpfile();#else//codeforWindows;#endif}然后,作者以为如许完成很欠好,会发明名字抵触,由于如许一来这个函数太丢脸了。因而他重构了一下他的代码——写一个本人完成的tmpfile()–w32_tmpfile,然后,在Windows下用宏界说来重定名这个函数为tmpfile()。(这类用法是对照尺度的跨平台代码的写法)
#ifdef_WIN32#definetmpfilew32_tmpfile#endifFILE*w32_tmpfile(void){//codeforWindows;}弄定!编译程序,运转。靠!竟然没有挪用到我的w32_tmpfile(),甚么成绩?调试,单步跟踪,公然没有挪用到!岂非是问号表达式有成绩?改成if–else语句,好了!
if(NULL!=fname){g=fopen(fname,"w+");}else{g=tmpfile();}问号表达式不该该有成绩吧,岂非我们的宏对问号表达式不起感化,这岂非是编译器的预编译的一个bug?作者嫌疑到。
如今我们把一切的代码连在一同看,并对照一下:
能一般事情的代码
#ifdef_WIN32#definetmpfilew32_tmpfile#endifFILE*w32_tmpfile(void){codeforWindows;}elseif(code==200){//Downloadingwholefile/*Writenewfile(plusallowreadingoncewefinish)*///FIXMEWin32nativeversionfailsherebecause//Microsoftsversionoftmpfile()createsthefileinC://g=fname?fopen(fname,"w+"):tmpfile();if(NULL!=fname){g=fopen(fname,"w+");}else{g=tmpfile();}}不克不及一般事情的代码
#ifdef_WIN32#definetmpfilew32_tmpfile#endifFILE*w32_tmpfile(void){codeforWindows;}elseif(code==200){//Downloadingwholefile/*Writenewfile(plusallowreadingoncewefinish)*///FIXMEWin32nativeversionfailsherebecause//Microsoftsversionoftmpfile()createsthefileinC:g=fname?fopen(fname,"w+"):tmpfile();}大概你在一入手下手就看到了这个bug,可是作者没有。一切的成绩都出在正文上:
/*Writenewfile(plusallowreadingoncewefinish)*///FIXMEWin32nativeversionfailsherebecause//Microsoftsversionoftmpfile()createsthefileinC:你看到了最初谁人C:吗?在C中,“”代表此行没有停止,因而,前面的代码同样成了正文。这就是这个bug的真正缘故原由!
而之以是改成if-else能事情的缘故原由是由于作者正文了老的问号表达式的代码,以是,那段能事情的代码成了:
/*Writenewfile(plusallowreadingoncewefinish)*///FIXMEWin32nativeversionfailsherebecauseMicrosoftsversionoftmpfile()createsthefileinC://g=fname?fopen(fname,"w+"):tmpfile();if(NULL!=fname){g=fopen(fname,"w+");}else{g=tmpfile();}我信任,看成者找到这个成绩的缘故原由后,必定会骂一句“妈的”!我也信任,这个bug消费了作者良多工夫!
最初,我也share一个我之前犯的一个错。
我有一个小函数,必要传进一个int*pInt的范例,然后我必要在我的代码里把这个int*pInt作除数。因而我的代码成了上面的这个模样:
floatresult=num/*pInt;
….
/*somecomments*/
-x<10?f(result):f(-result);
由于我在我事先用vi编写代码,以是没有语法高亮,而我的程序都编译经由过程了,可是却呈现了很奇异的事。我也不晓得,用gdb调式的时分,发明有些语句间接就过了。这个成绩让我花了良多工夫,最初发明成绩本来是没有空格招致的,TNND,上面我用代码高亮的插件来显现下面的代码,
floatresult=num/*pInt;..../*somecomments*/-x<10?f(result):f(-result);HollyShit!我的代码成了:
elseif(code==200){//Downloadingwholefile/*Writenewfile(plusallowreadingoncewefinish)*///FIXMEWin32nativeversionfailsherebecause//Microsoftsversionoftmpfile()createsthefileinC:g=fname?fopen(fname,"w+"):tmpfile();}0妈的!我的这个毛病在愚昧水平上和下面谁人作者出的毛病有一拼。
系统安全相关命令:passwd、su、umask、chgrp、chmod、chown、chattr、sudo、pswho 去年年内看完了C++PrimerPlus,但是感觉那本书太啰嗦,字小纸大,看得好累~看完第15章,后面两章就没看了。 简单的双重for循环就搞定的都要想半天那样,现在上研了,迫于实验室项目的需要,又重新拿起C++课本开始看。 现在的年轻人,清一色的追求看书看国外教材,当然我也不能低人一个档次,看的都是有名的大师作品,不期自己能够编出惊天地泣鬼神的大作。 我也学习了几天VB,然后不敢示弱得心把我拉回去,也不知道怎么回事,有一天灵感光顾,就这样,轻松进门,只用了一周。以后学习数据库编程,Socket编程也遇到类似得情况, 关于看书和实践。书本给我们的只能是原理上的介绍,而作为工科学生,以后不是需要你去写本书,或者讲节课,所以实践的过程就很关键,从看程序对原理的理解,到自己写程序的实战都是对编程思维很好的提高。 关于看书和实践。书本给我们的只能是原理上的介绍,而作为工科学生,以后不是需要你去写本书,或者讲节课,所以实践的过程就很关键,从看程序对原理的理解,到自己写程序的实战都是对编程思维很好的提高。 关于C++与C语言的规范化问题。众所周知,C++是从C语言发展而来的,所以在C++中就不可避免的夹杂些C留下来的糟粕(使用C语言的请见谅)。 记住: 不要放了基础. 多实践. 学程序时养成好习惯. 这包括程序要写得清晰.明了.就像写作一样.
页:
[1]