0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

就算你是高手你也會(huì)犯的Bug

GReq_mcu168 ? 來(lái)源:知曉編程 ? 作者:知曉編程 ? 2022-05-12 09:46 ? 次閱讀

我相信這樣的bug,就算你是高手你也會(huì)犯的。你來(lái)看看作者犯的這個(gè)Bug吧。。

首先,作者想用一段程序來(lái)創(chuàng)建一個(gè)文件,如果有文件名的話,就創(chuàng)建真正的文件,如果沒(méi)有的話,就調(diào)用tmpfile()創(chuàng)建臨時(shí)文件。

他這段程序就是HTTP下載的C程序。code==200就是HTTP的返回碼。

elseif(code==200){//Downloadingwholefile
/*Writenewfile(plusallowreadingoncewefinish)*/
g=fname?fopen(fname,"w+"):tmpfile();
}

但是這個(gè)程序,只能在Unix/Linux下工作,因?yàn)?Microsoft 的tmpfile()的實(shí)現(xiàn)居然選擇了 C: 作為臨時(shí)文件的存放目錄,這對(duì)于那些沒(méi)有管理員權(quán)限的人來(lái)說(shuō)就出大問(wèn)題了。在Windows 7下,就算你有管理員權(quán)限也會(huì)有問(wèn)題。

所以,上面的程序在Windows平臺(tái)下需要用不同的方式來(lái)處理,不能直接使用Windows的tmpfile()函數(shù)。

于是作者就先把這個(gè)問(wèn)題記下來(lái),在注釋中寫下了FIXME:

elseif(code==200){//Downloadingwholefile
/*Writenewfile(plusallowreadingoncewefinish)*/

//FIXMEWin32nativeversionfailsherebecause
//Microsoft'sversionoftmpfile()createsthefileinC:
g=fname?fopen(fname,"w+"):tmpfile();
}

然后,作者覺(jué)得需要寫一個(gè)跨平臺(tái)的編譯:

FILE*tmpfile(void){
#ifndef_WIN32
returntmpfile();
#else
//codeforWindows;
#endif
}

然后,作者覺(jué)得這樣實(shí)現(xiàn)很不好,會(huì)發(fā)現(xiàn)名字沖突,因?yàn)檫@樣一來(lái)這個(gè)函數(shù)太難看了。

于是他重構(gòu)了一下他的代碼——寫一個(gè)自己實(shí)現(xiàn)的tmpfile() – w32_tmpfile,然后,在Windows 下用宏定義來(lái)重命名這個(gè)函數(shù)為tmpfile()。(注:這種用法是比較標(biāo)準(zhǔn)的跨平臺(tái)代碼的寫法)

#ifdef_WIN32
#definetmpfilew32_tmpfile
#endif

FILE*w32_tmpfile(void){
//codeforWindows;
}

搞定!編譯程序,運(yùn)行。

靠!居然沒(méi)有調(diào)用到我的w32_tmpfile(),什么問(wèn)題?調(diào)試,單步跟蹤,果然沒(méi)有調(diào)用到!

難道是問(wèn)號(hào)表達(dá)式有問(wèn)題?改成if – else 語(yǔ)句,好了!

if(NULL!=fname){
g=fopen(fname,"w+");
}else{
g=tmpfile();
}

問(wèn)號(hào)表達(dá)式不應(yīng)該有問(wèn)題吧,難道我們的宏對(duì)問(wèn)號(hào)表達(dá)式不起作用,這難道是編譯器的預(yù)編譯的一個(gè)bug?作者懷疑到。

現(xiàn)在我們把所有的代碼連在一起看,并比較一下:

能正常工作的代碼

#ifdef_WIN32
#definetmpfilew32_tmpfile
#endif

FILE*w32_tmpfile(void){
codeforWindows;
}

elseif(code==200){//Downloadingwholefile
/*Writenewfile(plusallowreadingoncewefinish)*/
//FIXMEWin32nativeversionfailsherebecause
//Microsoft'sversionoftmpfile()createsthefileinC:
//g=fname?fopen(fname,"w+"):tmpfile();
if(NULL!=fname){
g=fopen(fname,"w+");
}else{
g=tmpfile();
}
}

不能正常工作的代碼

#ifdef_WIN32
#definetmpfilew32_tmpfile
#endif

FILE*w32_tmpfile(void){
codeforWindows;
}

elseif(code==200){//Downloadingwholefile
/*Writenewfile(plusallowreadingoncewefinish)*/
//FIXMEWin32nativeversionfailsherebecause
//Microsoft'sversionoftmpfile()createsthefileinC:
g=fname?fopen(fname,"w+"):tmpfile();
}

也許你在一開(kāi)始就看到了這個(gè)bug,但是作者沒(méi)有。所有的問(wèn)題都出在注釋上:

/*Writenewfile(plusallowreadingoncewefinish)*/
//FIXMEWin32nativeversionfailsherebecause
//Microsoft'sversionoftmpfile()createsthefileinC:

你看到了最后那個(gè)C:嗎?在C中,“” 代表此行沒(méi)有結(jié)束,于是,后面的代碼也成了注釋。這就是這個(gè)bug的真正原因

而之所以改成if-else能工作的原因是因?yàn)樽髡咦⑨屃死系膯?wèn)號(hào)表達(dá)式的代碼,所以,那段能工作的代碼成了:

/*Writenewfile(plusallowreadingoncewefinish)*/
//FIXMEWin32nativeversionfailsherebecauseMicrosoft'sversionoftmpfile()createsthefileinC://g=fname?fopen(fname,"w+"):tmpfile();
if(NULL!=fname){
g=fopen(fname,"w+");
}else{
g=tmpfile();
}

我相信,當(dāng)作者找到這個(gè)問(wèn)題的原因后,一定會(huì)罵一句“媽的”!我也相信,這個(gè)bug花費(fèi)了作者很多時(shí)間!

最后,我也share一個(gè)我以前犯的一個(gè)錯(cuò)。

我有一個(gè)小函數(shù),需要傳入一個(gè)int* pInt的類型,然后我需要在我的代碼里 把這個(gè)int* pInt作除數(shù)。于是我的代碼成了下面的這個(gè)樣子:

float result = num/*pInt; ….

/* some comments */

-x<10 ? f(result):f(-result);

因?yàn)槲以谖耶?dāng)時(shí)用vi編寫代碼,所以沒(méi)有語(yǔ)法高亮,而我的程序都編譯通過(guò)了,但是卻出現(xiàn)了很奇怪的事。

我也不知道,用gdb調(diào)式的時(shí)候,發(fā)現(xiàn)有些語(yǔ)句直接就過(guò)了。

這個(gè)問(wèn)題讓我花了很多時(shí)間,最后發(fā)現(xiàn)問(wèn)題原來(lái)是沒(méi)有空格導(dǎo)致的,TNND,下面我用代碼高亮的插件來(lái)顯示上面的代碼,

floatresult=num/*pInt;
....

/*somecomments*/

-x<10?f(result):f(-result);

Holly Shit! 我的代碼成了:

floatresult=num-x<10?f(result):f(-result);

我的這個(gè)錯(cuò)誤在愚蠢程度上和上面那個(gè)作者出的錯(cuò)誤有一拼。

審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    180

    文章

    7575

    瀏覽量

    134209
  • BUG
    BUG
    +關(guān)注

    關(guān)注

    0

    文章

    155

    瀏覽量

    15628

原文標(biāo)題:C語(yǔ)言史上最愚蠢的Bug

文章出處:【微信號(hào):mcu168,微信公眾號(hào):硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    stm32H7 HAL庫(kù)中存在的bug

    stm32H7 hal 庫(kù)里面的以太網(wǎng)代碼,坑了魚鷹很多次(不知道最新版是否已經(jīng)修復(fù)了這些bug),這里分享一篇網(wǎng)上的文章,因?yàn)轸~鷹遇到過(guò),靠它解決了其中一個(gè)編譯優(yōu)化問(wèn)題,在此感謝作者。不過(guò)hal
    的頭像 發(fā)表于 08-12 17:37 ?407次閱讀

    助力程序員告別困擾已久的夢(mèng)魘-Bug

    程序員的噩夢(mèng)是什么?不用懷疑,就是讓加班到崩潰的Bug!下面是經(jīng)過(guò)業(yè)界大佬們“長(zhǎng)期加班”積累的小妙招,助力離早下班又進(jìn)一步~一、定位Bug范圍及性質(zhì)要有效解決問(wèn)題,首先要縮小范圍,
    的頭像 發(fā)表于 07-02 08:10 ?167次閱讀
    助力程序員告別困擾已久的夢(mèng)魘-<b class='flag-5'>Bug</b>

    網(wǎng)絡(luò)會(huì)堵車?!3大法寶可以搞定它!

    高速公路會(huì)堵車,網(wǎng)絡(luò)這條信息的高速公路會(huì)堵。每次小長(zhǎng)假,相信大家一定對(duì)堵在高速路上一動(dòng)不動(dòng)的痛苦經(jīng)歷深有體會(huì)。因?yàn)榈缆穼捳徒煌üぷ魅藛T處理工作效率有限,導(dǎo)致車流量在短時(shí)間內(nèi)達(dá)到高峰就會(huì)造成堵車
    的頭像 發(fā)表于 05-21 08:05 ?445次閱讀
    網(wǎng)絡(luò)<b class='flag-5'>也</b><b class='flag-5'>會(huì)</b>堵車?!3大法寶可以搞定它!

    BUG收集】為昕原理圖設(shè)計(jì)EDA軟件(Jupiter)免費(fèi)評(píng)測(cè)活動(dòng)常見(jiàn)問(wèn)題及BUG收集

    感謝各位參與評(píng)測(cè)活動(dòng)的工程師,請(qǐng)先認(rèn)真閱讀評(píng)測(cè)規(guī)則和本帖頂部的視頻講解。 如遇到bug可以在本帖反饋,會(huì)由為昕EDA的工程師們?yōu)楦魑唤獯稹?【軟件及使用指南】 軟件使用指南見(jiàn)本帖底部視頻 軟件本體請(qǐng)
    發(fā)表于 04-25 18:23

    如何成為一名嵌入式C語(yǔ)言高手?

    嵌入式C語(yǔ)言領(lǐng)域獲得突出的技能和能力。 一、打下堅(jiān)實(shí)的基礎(chǔ)要成為一名嵌入式C語(yǔ)言高手,首先需要打下堅(jiān)實(shí)的基礎(chǔ)。掌握C語(yǔ)言的基本語(yǔ)法、數(shù)據(jù)類型、運(yùn)算符、控制流程和函數(shù)等概念是必不可少的。可以通過(guò)學(xué)習(xí)
    發(fā)表于 04-07 16:03

    如何成為一名嵌入式C語(yǔ)言高手?

    嵌入式C語(yǔ)言領(lǐng)域獲得突出的技能和能力。 一、打下堅(jiān)實(shí)的基礎(chǔ)要成為一名嵌入式C語(yǔ)言高手,首先需要打下堅(jiān)實(shí)的基礎(chǔ)。掌握C語(yǔ)言的基本語(yǔ)法、數(shù)據(jù)類型、運(yùn)算符、控制流程和函數(shù)等概念是必不可少的。可以通過(guò)學(xué)習(xí)
    發(fā)表于 03-25 14:12

    STM32高手進(jìn)階之路與實(shí)用學(xué)習(xí)步驟

    CPU是相通的,相信大部分的同學(xué)都學(xué)習(xí)過(guò)單片機(jī),是有一定基礎(chǔ)的。如果碰到問(wèn)題,去嘗試了,自己把問(wèn)題解決了,會(huì)很有成就感!
    的頭像 發(fā)表于 03-13 09:38 ?500次閱讀

    逆變器的保險(xiǎn)絲與斷路器區(qū)分,電線會(huì)熔化

    使用一次。斷路器成本更高,但可以重復(fù)使用,而且容量更大。保險(xiǎn)絲是由一根包在玻璃里的金屬絲組成的。如果逆變器突然出現(xiàn)電涌,保險(xiǎn)絲盒將會(huì)斷裂。如果溫度足夠高,電線會(huì)熔化
    的頭像 發(fā)表于 01-15 11:08 ?679次閱讀
    逆變器的保險(xiǎn)絲與斷路器區(qū)分,電線<b class='flag-5'>也</b><b class='flag-5'>會(huì)</b>熔化

    暫停Debian的升級(jí):內(nèi)核 6.1.64 ext4 Bug警報(bào)

    Debian 開(kāi)發(fā)人員正在積極尋找解決方案,并會(huì)在其可用時(shí)提供更新。與此同時(shí),用戶可以通過(guò)訪問(wèn)此處的 Debian bug 追蹤頁(yè)面了解該 bug 的進(jìn)展情況并獲取更多信息。
    的頭像 發(fā)表于 12-10 14:53 ?943次閱讀
    暫停Debian的升級(jí):內(nèi)核 6.1.64 ext4 <b class='flag-5'>Bug</b>警報(bào)

    無(wú)符號(hào)整型能產(chǎn)生哪些bug?

    為什么不建議使用無(wú)符號(hào)整型,無(wú)符號(hào)整型能產(chǎn)生哪些bug
    的頭像 發(fā)表于 11-09 17:09 ?403次閱讀
    無(wú)符號(hào)整型能產(chǎn)生哪些<b class='flag-5'>bug</b>?

    常見(jiàn)的PLC系統(tǒng)BUG有哪些?如何減少這些BUG的產(chǎn)生?

    PLC系統(tǒng)可能會(huì)遇到各種不同類型的BUG,以下是一些常見(jiàn)的PLC系統(tǒng)BUG以及如何減少這些BUG的產(chǎn)生的建議: (1)邏輯錯(cuò)誤:邏輯錯(cuò)誤是最常見(jiàn)的PLC系統(tǒng)
    的頭像 發(fā)表于 10-31 11:30 ?821次閱讀
    常見(jiàn)的PLC系統(tǒng)<b class='flag-5'>BUG</b>有哪些?如何減少這些<b class='flag-5'>BUG</b>的產(chǎn)生?

    常見(jiàn)的PLC系統(tǒng)BUG有哪些?如何減少BUG的產(chǎn)生呢?

    PLC系統(tǒng)可能會(huì)遇到各種不同類型的BUG,以下是一些常見(jiàn)的PLC系統(tǒng)BUG以及如何減少這些BUG的產(chǎn)生的建議
    的頭像 發(fā)表于 10-31 11:29 ?761次閱讀

    哪些錯(cuò)誤PLC新手容易?

    PLC新手在使用和編程PLC時(shí)容易以下一些常見(jiàn)錯(cuò)誤: (1)電氣接線錯(cuò)誤:PLC的輸入和輸出需要正確地與外部設(shè)備進(jìn)行連接。新手可能會(huì)接線錯(cuò)誤,例如接錯(cuò)線圈端子、斷開(kāi)或短路電線等。這可能導(dǎo)致PLC
    的頭像 發(fā)表于 10-11 17:10 ?714次閱讀

    STM8用串口下載及調(diào)試

    ,速度飛快.配合 IAR 或常用的 STVD,就算你沒(méi)有ST-LINK,一樣可以輕松實(shí)現(xiàn)程序開(kāi)發(fā).下面給出通過(guò)串口下載程序及配合 STVD進(jìn)行調(diào)試的具體操作流程,供有需要的朋友參考.
    發(fā)表于 10-10 08:04

    電路圖能看懂

    電子發(fā)燒友網(wǎng)站提供《電路圖能看懂.pdf》資料免費(fèi)下載
    發(fā)表于 10-07 09:58 ?33次下載