<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          握艸,C你main??!

          共 5665字,需瀏覽 12分鐘

           ·

          2024-06-25 08:23

          我看了這代碼這問題,直呼“握草”,main的!
          事情是這樣的,前段時間來了個新項目,大家都太忙了,沒人積極搞啊。于是,領(lǐng)導(dǎo)啟用了他前不久招的“得意門生”,把這活兒交給他了。
          這項目其實也沒很多活要干,最主要的是要從一個C++項目代碼移植到平臺的基礎(chǔ)工程里,當(dāng)然這個基礎(chǔ)工程是C語言的。
          這小伙,一頓操作猛如虎,風(fēng)風(fēng)火火搞了幾周,基本功能終于跑起來了!
          領(lǐng)導(dǎo)心想:哎呀果然沒看錯人。接著沒幾天領(lǐng)導(dǎo)就向上面領(lǐng)導(dǎo)吹捧一番,說這項目怎樣怎樣難,這誰誰又怎么怎么排除萬難的,最終搞出來了。反正,領(lǐng)導(dǎo)開心,小伙的績效也差不了哪去了!
          直到最近,出了一個bug,離奇古怪,某功能在你意想不到的情況下出錯。領(lǐng)導(dǎo)又派出了他的“得意門生”,噼里啪啦的,搞了一個多星期了,啥頭緒也沒有……
          這問題可被甲方發(fā)現(xiàn)了的,而且臨近交付樣品了,這把領(lǐng)導(dǎo)急的不要不要的。
          領(lǐng)導(dǎo)憋出了個大招,“三個臭皮匠頂個諸葛亮”,發(fā)動整個小組找bug……
          尼瑪,我也被牽連了,翻了半天也沒頭緒,這代碼一坨坨的具體是啥含義,我也懶得去研究。
          干脆直接編譯,準(zhǔn)備仿真看看的,一段編譯警告有點陌生,又特別礙眼,類似長這樣的:
          [elxr] (warning #222) The program contains no reference to _ctors.The following C++ dynamic initialization routines will probably not get called: ___sti___12_cpp_main_cpp_mm    from cpp_main.omain() (from c_main.o) was probably not compiled as C++.
          呵呵,這只是個warning,估計那小伙也不care!
          我第一次見這種warning,很好奇,也還不清楚是否跟這個問題有關(guān),不過我預(yù)感八九不離十了。
          怎么排查或者確認(rèn)這個warning就是因為項目的那個問題呢?
          1. 直接仿真,查看匯編,這個___sti___12_cpp_main_cpp_mm是什么玩意

          這個其實不好看懂,但能肯定的是,在仿真時,它沒被調(diào)用!
          2. 查網(wǎng)絡(luò)內(nèi)容或者查看編譯手冊
          也不好找到直接的答案,但能知道這個_ctor是C++的構(gòu)造函數(shù),另外還有個叫_dtor。
          綜合上面的信息看,好像是在說C++的構(gòu)造函數(shù)沒有調(diào)用,這個構(gòu)造函數(shù)又跟___sti___12_cpp_main_cpp_mm有關(guān)。
          3. 直接問AI
          其實也不用那么麻煩,現(xiàn)在什么年代了,有AI啊,直接問
          雖然沒有找到具體的問題點,但是可以大概找到,這個warning說,這個代碼里面有C++的構(gòu)造函數(shù)沒調(diào)用,也提到這個C++動態(tài)初始化函數(shù)___sti___12_cpp_main_cpp_mm沒調(diào)用。
          下一步呢?
          別急,看看這個函數(shù)名字,是不是帶個main的……
          大膽猜測,那是不是跟main函數(shù)有關(guān)?
          也許你會去看看那個main函數(shù),好像也沒什么特別錯誤?。?
          但是呢,不妨將想象力放開點,是不是說main函數(shù)要調(diào)用這個___sti___12_cpp_main_cpp_mm呢?
          等等,你是說main函數(shù)要調(diào)用一個C++的動態(tài)初始化函數(shù)?構(gòu)造函數(shù)來的?
          ___sti___12_cpp_main_cpp_mm這種函數(shù)也不像是直接在main函數(shù)調(diào)用的啊!
          ??!不對,這個是C語言文件里的main函數(shù),握草,應(yīng)該是C艸函數(shù)!
          是不是將main函數(shù)里的xxx.c改成xxx.cpp就好了呢?
          好激動哦,我是不是快找到問題原因了……
          直接試了下,還真是,C你main的,居然跟C艸不一樣!
          我壓制住我心中的激動,讓領(lǐng)導(dǎo)和那幫家伙再愁一會,我還沒搞清楚C main和C++ main的區(qū)別,不然被領(lǐng)導(dǎo)追問,我說不出來來龍去脈,豈不是說我亂猜的,瞎貓碰到死耗子,沒啥技術(shù)含量!哼!
          我接著,仿真了C語言和C++的main函數(shù)。
          發(fā)現(xiàn)C++的main多了點東西:


          仿真C++ main的匯編可以看到__main是庫里面的函數(shù),其會調(diào)用這個___sti___12_cpp_main_cpp_mm函數(shù)。
          這樣,我可以告訴領(lǐng)導(dǎo)我找到問題原因了嗎?
          我還是選擇等等。因為,這樣無法說明怎么直接導(dǎo)致了項目的那個問題??!并且,有些項目C和C++混合的工程,用C語言main函數(shù)也沒問題啊,而且也沒提示那個warning!
          如果領(lǐng)導(dǎo)問我,我也說不出為什么,他還是會說我猜的!
          為了保證,我的回答萬不一失,我選擇低調(diào)繼續(xù)研究下。
          再回頭看看AI回答的那段話,它提到了構(gòu)造函數(shù)和靜態(tài)對象,難道是靜態(tài)對象的初始化賦值問題?
          于是,我嘗試了好多次不同的場景,終于模擬出了這種情況。(我把完整測試源碼附在文末)
          typedef struct{  unsigned int  id;  unsigned char   len;} Msg;class Test {    public:        Test() {      }        int n;        static int st_n;        static Msg st_m;};Msg mm={0xaa,0x55};Msg Test::st_m = mm;int Test::st_n = 0x123;
          其實,這個___sti___12_cpp_main_cpp_mm函數(shù)里面就是靜態(tài)變量的初始化!
          這里這個-0x142FF94值,即0xFEBD006C,實際是對應(yīng)MAP文件中的.bss段中的_st_m__4Test變量。
           .data            febd0000+000008 _mm .text            00000b9e+000002 _multiBreak .text            00000b9a+000000 _multiCall .text            00001b2c+00004a _open .text            000018b6+000084 _raise .text            00001b06+000026 _read .text            00001856+000060 _signal .bss             febd006c+000008 _st_m__4Test .data            febd0008+000004 _st_n__4Test
          那么,這個_st_m__4Test變量是什么呢?就是上面代碼Test類的靜態(tài)成員st_m。此時很容易就能理解到,這個___sti___12_cpp_main_cpp_mm函數(shù)就是執(zhí)行了Msg Test::st_m = mm;的賦值。匯編中的-0x1430000就是對應(yīng)MAP中.data段的_mm變量,就是Msg mm={0xaa,0x55};這個變量。通過仿真就可以證實這些內(nèi)容。
          所以,C++的main跟C的main不一樣,C++的main更有內(nèi)涵,其中還藏著一個__main,且其里面還執(zhí)行了靜態(tài)成員的初始化。
          • C的main,性格直爽,心里不藏任何秘密;
          • C++的main,內(nèi)斂且有內(nèi)涵,還悄悄地幫你做靜態(tài)成員初始化。
          所以,你喜歡誰的main?
          好了,話題扯遠(yuǎn)了,這下我應(yīng)該可以向領(lǐng)導(dǎo)匯報了吧。
          于是,我打算好好科普C和C++的main main的時候,領(lǐng)導(dǎo)卻說,那誰誰已經(jīng)再同步C++項目的啟動部分文件就OK了,而且已經(jīng)檢討移植項目文件不徹底問題了,問題已經(jīng)解決了。于是,讓我去忙別的去了。
          我……欲言又止……
          main的,艸!

          測試源碼
          // c_main.cextern int test_func(void);#ifndef CPP_MAINint main(void){    test_func();    return 0;}#endif


          // cpp_main.cpptypedef struct{ unsigned int id; unsigned char len;} Msg;class Test { public: Test() { } int n; static int st_n; static Msg st_m;};Msg mm={0xaa,0x55};Msg Test::st_m = mm;int Test::st_n = 0x123;Test gt; extern "C" { int test_func(void){ Test t; int x; t.n = 12; if(t.st_n == 0x123) { x = 100; } if(t.st_m.id == 0xaa) { x = 200; } if(gt.st_m.id == 0xaa) { x = 2200; } return x; }}#ifdef CPP_MAINint main(){ test_func(); return 0;}#endif

          我知道你看完本文就退出的了,就算收藏也是吃灰的,不如你點個轉(zhuǎn)發(fā)、點贊在看再走,我是會很感激你的哦!

          瀏覽 404
          4點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          4點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  人妻日韩精品中文字幕 | 免费操屄网 | 欧美乱三级 | 日逼视频网站 | 少妇操屄视频 |