• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            static 變量初始化順序引發(fā)的bug

            沒想到會遇到這樣的問題,

            在VC6環(huán)境下測試,重點請看紅色字體與圖片。

             

            #include "stdafx.h"

            #include <stdio.h>

             

            typedef struct sData

            {

                static const char* text;

                static int  val_a;

                static int  val_b;

            } sData, *Self_Ptr;

             

            typedef struct 

            {

                char* text;

                int val_a;

                int val_b;

            }* Other_Ptr;

             

             

            const char* sData::text = "this is a test string\0";

            int   sData::val_b = 200;

            int   sData::val_a = 100;

             

            int main(int argc, char* argv[])

            {

                Self_Ptr p_self = (Self_Ptr)&(sData::text);

                Other_Ptr p_other = (Other_Ptr)&(sData::text);

                printf("%d\n", sizeof(sData));                          //----1, static成員不計入sizeof

                printf("val_a: %d-%d\n", p_self->val_a, sData::val_a);  //----val_a: 100-100

                printf("val_b: %d-%d\n", p_self->val_b, sData::val_b);  //----val_b: 200-200

                printf("val_a: %d-%d\n", p_self->val_a, p_other->val_a);//----val_a: 100-200

                printf("val_b: %d-%d\n", p_self->val_b, p_other->val_b);//----val_b: 200-100

                return 0;

            }

             

            image

            posted on 2008-12-03 21:38 肥仔 閱讀(3436) 評論(14)  編輯 收藏 引用 所屬分類: C++ 基礎(chǔ)

            評論

            # re: static 變量初始化順序引發(fā)的bug  回復(fù)  更多評論   

            這都什么啊……
            類靜態(tài)成員變量是鏈接進代碼段的東西,同一個類中靜態(tài)成員變量的地址沒有誰向你保證過會連續(xù)的,三個變量三個完全不相干的地址都是完全合理的,你應(yīng)該反思的是從一個靜態(tài)成員地址反推其他靜態(tài)成員地址這種完全不符合邏輯的做法。
            另外,你的p_self->val_a之所以合法是因為它看的只是p_self的類型,編譯的時候發(fā)現(xiàn)是靜態(tài)成員就直接換成實際地址了。
            你可以把
            Self_Ptr p_self = (Self_Ptr)&(sData::text);
            換成
            Self_Ptr p_self = NULL;
            結(jié)果是一樣的。
            2008-12-03 22:56 | RedNax

            # re: static 變量初始化順序引發(fā)的bug  回復(fù)  更多評論   

            @RedNax
            如果我沒有記錯的話
            class不是POD,即使是非靜態(tài)成員,也不能保證連續(xù),標(biāo)準(zhǔn)沒有這樣的規(guī)定。
            成員為內(nèi)置內(nèi)型或POD類型且同時沒有成員函數(shù)的struct可以歸為POD了,標(biāo)準(zhǔn)規(guī)定POD內(nèi)存必須連續(xù),有static成員的struct還算不算POD,這個我倒是不知道。
            2008-12-03 23:17 | 肥仔

            # re: static 變量初始化順序引發(fā)的bug  回復(fù)  更多評論   

            @RedNax
            right, 你的判斷正確,換成Self_Ptr p_self = NULL; p_self->val_a不會內(nèi)存訪問違規(guī),說明編譯期已經(jīng)替換了p_self->val_a。
            2008-12-03 23:38 | 肥仔

            # re: static 變量初始化順序引發(fā)的bug  回復(fù)  更多評論   

            @RedNax
            根據(jù)你的提示,測試了另一個種情況,證明內(nèi)存確實不連續(xù),與定義順序相關(guān) +編譯器相關(guān)。

            我找到了一種強制內(nèi)存連續(xù)的辦法,接口轉(zhuǎn)換也OK,但代碼不好看了,如下:


            #include "stdafx.h"
            #include <stdio.h>

            typedef struct
            {
            struct __Data
            {
            char* text;
            int val_a;
            int val_b;
            } static data;

            } sData, *Self_Ptr;

            typedef struct
            {
            char* text;
            int val_a;
            int val_b;
            }* Other_Ptr;

            sData::__Data sData::data
            ={ "this is a test string\0", 100, 200};

            int main(int argc, char* argv[])
            {
            Self_Ptr p_self = 0;
            Other_Ptr p_other = (Other_Ptr)&(sData::data.text);
            printf("%d\n", sizeof(sData));
            printf("val_a: %d-%d\n", p_self->data.val_a, sData::data.val_a);
            printf("val_b: %d-%d\n", p_self->data.val_b, sData::data.val_b);
            printf("val_a: %d-%d\n", p_self->data.val_a, p_other->val_a);
            printf("val_b: %d-%d\n", p_self->data.val_b, p_other->val_b);
            return 0;
            }
            2008-12-04 00:03 | 肥仔

            # re: static 變量初始化順序引發(fā)的bug  回復(fù)  更多評論   

            還是搞不懂你這樣做是什么意思,要好看這樣就可以了吧:

            // #include "stdafx.h"
            #include <stdio.h>


            typedef struct
            {
            char* text;
            int val_a;
            int val_b;
            }__Data, *Other_Ptr;

            typedef struct sData
            {
            static __Data data;
            } *Self_Ptr;

            __Data sData::data
            ={ "this is a test string\0", 100, 200};

            int main(int argc, char* argv[])
            {
            Self_Ptr p_self = 0;
            Other_Ptr p_other = (Other_Ptr)&(sData::data);
            printf("%d\n", sizeof(sData));
            printf("val_a: %d-%d\n", p_self->data.val_a, sData::data.val_a);
            printf("val_b: %d-%d\n", p_self->data.val_b, sData::data.val_b);
            printf("val_a: %d-%d\n", p_self->data.val_a, p_other->val_a);
            printf("val_b: %d-%d\n", p_self->data.val_b, p_other->val_b);
            return 0;
            }
            2008-12-04 00:52 | RedNax

            # re: static 變量初始化順序引發(fā)的bug  回復(fù)  更多評論   

            @RedNax
            ?? 有差別嗎? 代碼不好看,我指p_self->data.val_a,多了一個data,能夠去掉這個data就好看了。

            因為項目中需要提供一個這樣的能力:有幾百個全部是static成員的struct,它們只有最后一個字段是個POD數(shù)組,長度會不同,需要有一個統(tǒng)一的接口來訪問這些struct的成員,所以做了這個測試。

            2008-12-04 10:35 | 肥仔

            # re: static 變量初始化順序引發(fā)的bug  回復(fù)  更多評論   

            C++的意愿是希望大家不要太關(guān)注內(nèi)存的布局,各個編譯器的內(nèi)存布局都是不太一樣的。

            標(biāo)準(zhǔn)規(guī)定POD內(nèi)存必須連續(xù)
            ----------------------
            C++標(biāo)準(zhǔn)嗎?98年的時候和VC6一起出現(xiàn),VC6能支持同一時期出現(xiàn)的標(biāo)準(zhǔn)?很明顯不能。用VC6的話,就不要把C++標(biāo)準(zhǔn)扯嘴上了。
            2008-12-04 11:47 | guest

            # re: static 變量初始化順序引發(fā)的bug  回復(fù)  更多評論   

            @guest
            汗,VC6如果對POD這樣的標(biāo)準(zhǔn)都支持不了,那就太那個。
            VC6一直在用,而且最近1~2年內(nèi)應(yīng)該還是會作為工作的首選,沒覺得有什么不好。賽揚CPU,512MB的內(nèi)存,開4個VC6 IDE,并行開發(fā)一點都不卡,舒舒服服。
            AMD雙核,2G內(nèi)存,打開一個VS 2008,只聽到硬盤狂叫,10秒以上才能出個界面,這就是.net的效果?。
            上次CSDN看到一個投票,目前C++集成開發(fā)環(huán)境,10年了的VC6占30%多,依然居第一位。



            2008-12-04 12:19 | 肥仔

            # re: static 變量初始化順序引發(fā)的bug  回復(fù)  更多評論   

            關(guān)于靜態(tài)成員的引用,“p_self->val_a”這種寫法雖然語法上沒有問題,但是一般編譯器都會直接認(rèn)為是“sData::val_a”,所以肯定沒有問題。
            而“p_other->val_a”出現(xiàn)了問題,確實是因為內(nèi)存有不連續(xù)的現(xiàn)象。static成員在運行時有可能是放到代碼段里的,其具體規(guī)劃很顯然會受編譯器和操作系統(tǒng)的影響;而一個普通的結(jié)構(gòu)題變量實際上是連續(xù)的放在棧里的。
            2008-12-04 13:21 | abettor

            # re: static 變量初始化順序引發(fā)的bug  回復(fù)  更多評論   

            @肥仔
            代碼里的問題和static變量初始化順序沒有關(guān)系...
            編譯器是編譯器,編輯器是編輯器,雖然微軟把他們綁成一個VC扔給博主,但博主最好還是把他們分清楚。喜歡VC6編輯器資源消耗小,沒問題,你就一直用VC6的IDE寫代碼;喜歡VC 2008的編譯器支持C++新標(biāo)準(zhǔn),沒問題,你就直接在在命令行用VC 2008的編譯器編譯就行了。不矛盾也不沖突。
            2008-12-05 16:47 | helpsoff.com.cn

            # re: static 變量初始化順序引發(fā)的bug  回復(fù)  更多評論   

            @helpsoff.com.cn
            呵呵,這不是我們第一次交流了,你這位同志比較喜歡好為人師嘛。但是需要說出點稍微有參考價值的東西,才可以教育別人,是不是。

            交流需要平等,干嘛老擺個姿態(tài)呢,我覺得不好。
            2008-12-05 18:44 | 肥仔

            # re: static 變量初始化順序引發(fā)的bug  回復(fù)  更多評論   

            不知道博主又從那句話看出來本人好為人師了?我說話一直就是這個樣子,你要是不喜歡,覺得我說的話沒有參考價值,都是P話,盡管刪了好了,反正這是你的地盤。

            說實話,上篇文章看你做把ASSERT和if綁在一起的傻事,自己把網(wǎng)頁一關(guān)就算了,管我P事。可偏偏又覺得不指出來,看著別人以做傻事為榮看不下去,結(jié)果好了,倒給博主卯上了。對我提了建議不入耳不說,還扣個帽子“擺姿態(tài)”。心想算了,多一事不如少一事。今天轉(zhuǎn)博客又轉(zhuǎn)到這里,看到這篇莫名其妙的代碼再加上對VC的偏見,氣又不打一出來。好吧,寫兩句說說。博主又說沒參考意義,再扣個帽子“好為人師”。博主,既然你覺得我們是在交流,請拿出你對我留言的看法來先,技術(shù)層面上的,不要先對人打上標(biāo)記帶上偏見,好嗎?

            回到我上一條留言,我想問問你,你真的弄清楚,裝完VC后,哪塊是編輯器,哪塊是編譯器鏈接器,哪塊是開發(fā)包了嗎?
            2008-12-05 19:33 | helpsoff.com.cn

            # re: static 變量初始化順序引發(fā)的bug  回復(fù)  更多評論   

            @helpsoff.com.cn
            呵呵,好了。

            我必須得承認(rèn),你很強,你問的問題讓我不知所措,我非常地茫然,幾乎無地自容。當(dāng)然不會刪你的留言,只要不是粗痞話,我都不會刪。大俠的更要留著偶爾看看,好讓自己感到自卑。

            這既然是一個你不屑的地方,就不必再來了吧,何必來看這么膚淺的文章影響了您老人家的心情?

            送客了,遠(yuǎn)方的客人請您別再來~~~,:)


            2008-12-05 21:00 | 肥仔

            # re: static 變量初始化順序引發(fā)的bug[未登錄]  回復(fù)  更多評論   

            。。。。。。。。。。。
            路過。。。。。。。。。
            。。。。。。。。。。。
            2008-12-07 11:22 | cppexplore
            国产精品99久久久久久宅男| 久久只有这精品99| 久久精品成人免费观看97| 亚洲а∨天堂久久精品| 国产精品久久久久久吹潮| 久久99精品国产麻豆不卡| 伊人久久精品无码av一区| 成人亚洲欧美久久久久| 亚洲AV无码久久精品成人| 国产精品无码久久久久| 欧美黑人又粗又大久久久| 久久免费大片| 2020最新久久久视精品爱| 亚洲人成网亚洲欧洲无码久久| 99国内精品久久久久久久 | 国产A级毛片久久久精品毛片| 狠狠色丁香久久婷婷综合_中 | 久久国产欧美日韩精品| 狠狠色丁香婷婷综合久久来来去| 亚洲日韩中文无码久久| 一97日本道伊人久久综合影院| 热99re久久国超精品首页| 人人狠狠综合久久88成人| 久久久免费观成人影院| 久久综合丁香激情久久| 久久精品九九亚洲精品| 综合网日日天干夜夜久久 | 亚洲欧洲日产国码无码久久99 | 久久这里只有精品18| 亚洲伊人久久综合中文成人网| 久久AⅤ人妻少妇嫩草影院| 久久99国产精品久久| 久久久久人妻一区二区三区vr| 欧美日韩久久中文字幕| 亚洲乱码日产精品a级毛片久久 | 久久超碰97人人做人人爱| 无码国内精品久久人妻| 午夜久久久久久禁播电影| 亚洲香蕉网久久综合影视| 奇米综合四色77777久久| 日韩人妻无码精品久久免费一|