青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Prayer

在一般中尋求卓越
posts - 1256, comments - 190, trackbacks - 0, articles - 0
  C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

64bit需要做的改變

Posted on 2009-10-09 09:29 Prayer 閱讀(974) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C/C++LINUX/UNIX/AIX
最近64bit以更低的代價(jià)開(kāi)放到了廣大的用戶面前,對(duì)于需要更大的內(nèi)存空間,或者更精確的浮點(diǎn)數(shù)計(jì)算的開(kāi)發(fā)者來(lái)說(shuō),無(wú)疑提供了更多的方便。這篇文章的目的是要讀者了解對(duì)于32bit的源代碼向64bit轉(zhuǎn)移所要做的工作。

事實(shí)上來(lái)說(shuō),32bit的代碼可以很方便的移植到64位機(jī)上,因?yàn)?4位提供了對(duì)32位很好的支持,只有在你有以下的需要的時(shí)候,嘗試去修改你的代碼

  • 獲得超過(guò)4GB內(nèi)存的支持。
  • 獲得超過(guò)2G大小文件的支持
  • 獲得更精確的浮點(diǎn)數(shù)運(yùn)算
  • 獲得64位機(jī)優(yōu)化的數(shù)學(xué)運(yùn)算庫(kù)

    否則,只需要重新編譯你的32位代碼,that's ok!

    1。ILP32和LP64 數(shù)據(jù)模式

    大多數(shù)unix系統(tǒng)的數(shù)據(jù)模式是采用LP64bit的,long和pointer是8個(gè)字節(jié)64位的,相對(duì)于32bit的4個(gè)字節(jié)。將來(lái)windows或許會(huì)采用一種數(shù)據(jù)模式LLP64,只是對(duì)于pointer采用64bit,其他的和32位一樣。這里以表格的方式顯示兩者之間的差別

    Data Type ILP32 (bits) LP64 (bits)
    char 8 No change
    short 16 No change
    int 32 No change
    long long 64 No change
    long 32 64
    pointer 32 64

    基本上移植到64bit的錯(cuò)誤都是來(lái)自誤以為int long pointer都是64bit的,實(shí)際則不然。下面是一個(gè)程序演示了這個(gè)錯(cuò)誤。

    1      int *myfunc(int i)
    2      {
    3               return(&i);
    4      }
    5
    6       int  main(void)
    7       {
    8               int     myint;
    9               long    mylong;
    10              int     *myptr;
    11
    12        char *name = (char * ) getlogin();
    13
    14                printf("Enter a number %s: ", name);
    15               (void) scanf("%d", &mylong);
    16                myint = mylong;
    17                myptr = myfunc(mylong);
    18                printf("mylong: %d  pointer: %x \n", mylong, myptr);
    19                myint = (int)mylong;
    20                exit(0);
    21
    22      }
    上面的代碼是錯(cuò)誤的,需要進(jìn)行修正。

    移植的第一項(xiàng)工作,是讓編譯器能檢測(cè)到64位的錯(cuò)誤。這根據(jù)編譯器的不同而變化。對(duì)于IBM的XL 編譯器家族來(lái)說(shuō),有用的參數(shù)是-qwarn64 -qinfo=pro. 把你的代碼編譯成64bit需要加上-q64,對(duì)于gcc編譯器來(lái)說(shuō)則是加上-m64,下面列舉一些編譯64位一些有用的gcc參數(shù)。

    Option Description
    -Wpadded Warns that padding was added to the structure.
    -Wformat Check calls to printf and scanf have correct format strings.
    -Wsign-compare Warn when a comparison between signed and unsigned values could produce an incorrect result when the signed value is converted to unsigned.
    -Wsign-compare Warn when a comparison between signed and unsigned values could produce an incorrect result when the signed value is converted to unsigned.
    -Wconversion Warn if a prototype causes a type conversion that is different from what would happen to the same argument in the absence of a prototype.
    -Wpointer-arith Warn about anything that depends on the function pointer or of void *.

    下面演示以下編譯上面代碼所出現(xiàn)的提示信息。

    %  xlc -q64  -qformat=all -qwarn64 test.c

    "test.c", line 12.30: 1506-745 (I) 64-bit portability: possible incorrect pointer through conversion of int type into pointer.
    "test.c", line 15.36: 1506-1191 (W) Invalid int format for long argument type in argument 2.
    "test.c", line 16.25: 1506-742 (I) 64-bit portability: possible loss of digits through conversion of long int type into int type.
    "test.c", line 17.32: 1506-742 (I) 64-bit portability: possible loss of digits through conversion of long int type into int type.
    "test.c", line 18.39: 1506-1191 (W) Invalid int format for long argument type in argument 2.
    "test.c", line 19.25: 1506-742 (I) 64-bit portability: possible loss of digits through conversion of long int type into int type.

    2。缺少原型的轉(zhuǎn)換方面的考慮

    上面的代碼char *name = (char * ) getlogin();

    會(huì)出現(xiàn)錯(cuò)誤的,32位的int要轉(zhuǎn)換成64位會(huì)出現(xiàn)錯(cuò)誤的,要避免這種錯(cuò)誤,include正確的頭文件<unistd.h>,里面有g(shù)etlogin()的原型。

    3。制定數(shù)據(jù)格式的錯(cuò)誤

    (void) scanf("%d", &mylong);

    要避免這個(gè)錯(cuò)誤,修改成這樣(void) scanf("%ld", &mylong);

    printf("mylong: %d  pointer: %x \n", mylong, myptr);
    修改成printf("mylong: %ld  pointer: %p \n", mylong, myptr);

    4.賦值的錯(cuò)誤

    myint = mylong;
    錯(cuò)誤出現(xiàn)在64位的值賦給32位的

    5.數(shù)值參數(shù)的傳輸錯(cuò)誤

    myptr = myfunc(mylong);會(huì)出現(xiàn)傳遞時(shí)的轉(zhuǎn)換類型錯(cuò)誤

    6.類型強(qiáng)制轉(zhuǎn)換出現(xiàn)的錯(cuò)誤

    myint = (int)mylong;

    int length = (int) strlen(str);
    在LP64模式中strlen返回的是unsigned long,雖然一般不會(huì)出現(xiàn)錯(cuò)誤,但是在大于2GB的時(shí)候,盡管不大可能,但是會(huì)出現(xiàn)潛在的錯(cuò)誤。

    7.更多的微妙的錯(cuò)誤

    編譯器會(huì)發(fā)現(xiàn)大多數(shù)的潛在的類型轉(zhuǎn)換方面的錯(cuò)誤,但是你不能僅僅依賴于編譯器。

    #define INVALID_POINTER_VALUE 0xFFFFFFFF
    在32位上上面的宏定義會(huì)被經(jīng)常地用來(lái)測(cè)試-1,但是在64位機(jī)上,這個(gè)數(shù)值卻不是-1,而是4294967295。在64位機(jī)上-1是0xFFFFFFFFFFFFFFFF。要避免這個(gè)錯(cuò)誤,利用const來(lái)聲明,并指定signed還是unsigned

    const signed int INVALID_POINTER_VALUE = 0xFFFFFFFF;
    上面的代碼在32位和64位機(jī)上都會(huì)工作的很好。

    還有就是32位機(jī)上的代碼如下

    int **p; p = (int**)malloc(4 * NO_ELEMENTS);
    這個(gè)代碼犯了如下的錯(cuò)誤就是認(rèn)為sizeof(int) ==  sizeof(int *)

    實(shí)際上在64位上是不對(duì)的。

    8.signed和unsigned的錯(cuò)誤

    long k;
    int i = -2;
    unsigned int j = 1;

    k = i +  j;

    printf("Answer: %ld\n", k);
    以上的代碼在32位機(jī)上會(huì)得出-1。但是在64位機(jī)上卻不是的。結(jié)果會(huì)是4294967295。原因是i+j得到的會(huì)是unsigned的值,而這個(gè)值卻會(huì)賦給long的k,要避免這個(gè)錯(cuò)誤,需要進(jìn)行修改如下:

    k = i + (int)j;

    9.union的錯(cuò)誤


    下面是一個(gè)很常見(jiàn)的結(jié)構(gòu)體:

    typedef struct {
        unsigned short bom;
        unsigned short cnt;
        union {
            unsigned long bytes;
            unsigned short len[2];
        } size;
    } _ucheader_t;
    32位機(jī)上會(huì)工作的很好,但是在64位機(jī)上不然。原因是64位機(jī)上long 等于4個(gè)short.要把unsigned long 修改成 unsigned int. 才能工作好。必須要注意這個(gè)細(xì)節(jié)。

    10.big endian和little endian導(dǎo)致的錯(cuò)誤

    在32位機(jī)上的代碼有些移植到64位機(jī)上出現(xiàn)錯(cuò)誤與否還和機(jī)器的big endian或者little endian有關(guān)。比如下面的代碼。

    long k;
    int *ptr;

    int main(void)
    {
        k = 2 ;
        ptr = &k;
        printf("k has the value %ld, value pointed to by ptr is %ld\n",              k, *ptr);
        return 0;
    }

    這段代碼在32bit機(jī)上編譯不會(huì)出現(xiàn)錯(cuò)誤,因?yàn)閘ong 和pointer都是32bit,但是在64位機(jī)上不然,盡管如此,如果在little endian的64位機(jī)上編譯的話,仍然會(huì)得到正確的2,但是在big endian的情況下,則會(huì)得到0。

    如果有疑問(wèn)的話,下面詳細(xì)解釋一下。

    Memory Address Little Endian LP64 Big Endian LP64
    0x0x7fbfffdca0 ptr 0x02 0x00
    0x0x7fbfffdca1 0x00 0x00
    0x0x7fbfffdca2 0x00 0x00
    0x0x7fbfffdca3 0x00 0x00
    0x0x7fbfffdca4 0x00 0x00
    0x0x7fbfffdca5 0x00 0x00
    0x0x7fbfffdca6 0x00 0x00
    0x0x7fbfffdca7 0x00

    0x02

    11.64位機(jī)上性能的降低

    這個(gè)問(wèn)題是由于64位機(jī)的數(shù)據(jù)結(jié)構(gòu)的膨脹,對(duì)于內(nèi)存需要的增加,以及存儲(chǔ)空間的增加所致。要減少這方面的損失,你可以精心改變你的數(shù)據(jù)結(jié)構(gòu)中變量定義的順序。比如下面的例子


     
    12.如何測(cè)試你的64位代碼

    定義一些宏來(lái)完成目標(biāo),下面是示例:

    #if defined (__LP64__) || defined (__64BIT__) || defined (_LP64) || (__WORDSIZE == 64)
       printf("I am LP64\n");
    #else
       printf("I am ILP32 \n");
    #endif

    13.64位文件和32位文件之間的彼此讀取問(wèn)題

    #include <stdio.h>
    #include <inttypes.h>

    struct on_disk
    {
       /* ILP32|LP64 Sharing Issue: This should change to int32_t */
       long foo;
    };
    int main()
    {
        FILE *file;
        struct on_disk data;
    #ifdef WRITE
            file=fopen("test","w");
            data.foo = 65535;
            fwrite(&data, sizeof(struct on_disk), 1, file);
    #else
            file = fopen("test","r");
            fread(&data, sizeof(struct on_disk), 1, file);
            printf("data: %ld\n", data.foo);
    #endif
        fclose(file);
    }          

    代碼不能很好地在32位和64為對(duì)同一個(gè)文件的操作過(guò)程中工作。要fix這個(gè)錯(cuò)誤,可以設(shè)置宏定義,以在64位機(jī)上對(duì)foo聲明為int32_t。要注意這個(gè)細(xì)節(jié)。

    14.fortran和c語(yǔ)言混合的問(wèn)題

    下面兩個(gè)程序演示了這個(gè)錯(cuò)誤

    void FOO(long *l);
    main ()
    {
       long l = 5000;
       FOO(&l);
    }

    subroutine foo( i )
    integer  i
    write(*,*) 'In Fortran'
    write(*,*) i
    return
    end subroutine foo

    要避免這個(gè)錯(cuò)誤,需要在fortran語(yǔ)言中把i聲明為INTEGER*8,這相當(dāng)于64位的long.

    最后,結(jié)論:64位機(jī)提供了對(duì)于更多的計(jì)算方面的更好的支持,盡管32位代碼一般來(lái)說(shuō)可以移植的很好,但是,得注意這些細(xì)節(jié)方面的問(wèn)題,這樣才能使你的代碼一直工作更順利。

    文章來(lái)源于http://www.lupaworld.com

  • 青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国产精品一区二区黑丝| 亚洲午夜精品久久| 亚洲永久精品大片| 亚洲欧美成人| 先锋资源久久| 久久永久免费| 欧美波霸影院| 欧美日韩麻豆| 国产色产综合产在线视频| 欧美日韩中文| 国内久久精品| 亚洲三级视频| 日韩一级精品视频在线观看| 亚洲国产综合在线| 亚洲欧美另类在线| 欧美91精品| 亚洲综合欧美| 欧美激情2020午夜免费观看| 国产精品毛片一区二区三区| 国产日韩欧美一区二区三区在线观看| 国产精品一区二区女厕厕| 亚洲激情视频| 欧美一级欧美一级在线播放| 欧美国产第一页| 欧美一区二区三区男人的天堂| 欧美+亚洲+精品+三区| 国产精品一二一区| 亚洲欧美日韩专区| 亚洲精品欧洲精品| 欧美国产日韩视频| 亚洲国产日韩欧美综合久久| 久久精品国产一区二区三区| 亚洲肉体裸体xxxx137| 亚洲午夜电影| 亚洲视频999| 欧美午夜a级限制福利片| 国产亚洲永久域名| 久久精品91| 在线观看成人一级片| 欧美一区激情| 久久综合999| 一本久久综合亚洲鲁鲁| 中文久久精品| 国产精品爽黄69| 久久综合伊人| 欧美激情一区二区三区全黄| 99re热这里只有精品视频 | 久色婷婷小香蕉久久| 国产一区二区三区久久悠悠色av| 欧美自拍偷拍| 欧美精品午夜| 久久精品亚洲一区| 欧美成人免费va影院高清| 亚洲一区在线看| 久久精品国产亚洲aⅴ| 亚洲一区二区三区影院| 久久国产一二区| 亚洲午夜一区二区| 欧美freesex8一10精品| 亚洲欧美中日韩| 欧美日韩蜜桃| 欧美国产视频日韩| 亚洲大胆av| 久久激情视频久久| 久久国产综合精品| 国产精品成人一区二区三区夜夜夜| 免费不卡欧美自拍视频| 一区二区三欧美| 国产综合欧美在线看| 亚洲色图自拍| 欧美一区二区三区在线看| 欧美日韩国产高清| 亚洲国产日韩一级| 亚洲精选成人| 欧美激情综合| 亚洲一区二区三区午夜| 久久riav二区三区| 国产精品实拍| 久久视频这里只有精品| 亚洲第一精品夜夜躁人人躁| 亚洲精品一区二区三区蜜桃久 | 欧美精品在线免费观看| 91久久精品一区二区三区| 99精品国产在热久久| 国产精品白丝黑袜喷水久久久 | 欧美亚洲自偷自偷| 国产伦精品一区二区三区视频黑人| 99v久久综合狠狠综合久久| 中文精品99久久国产香蕉| 欧美吻胸吃奶大尺度电影| 久久国产精品99久久久久久老狼| 欧美激情精品久久久久久大尺度| 一区二区三区视频在线播放| 国产精品网站视频| 欧美精品亚洲精品| 久久精品视频在线看| 亚洲视频综合| 夜夜嗨av一区二区三区网页| 可以免费看不卡的av网站| 欧美一区二区三区电影在线观看| 亚洲日本一区二区| 国产午夜精品福利| 一本大道久久a久久综合婷婷| 久久久精品动漫| 欧美亚洲一区在线| 先锋影音国产精品| 在线一区二区三区四区| 亚洲国产美女精品久久久久∴| 国产欧美一二三区| 国产乱码精品| 国产精品一区二区在线| 国产精品日韩在线观看| 精品成人在线| 久色成人在线| 久久久久久久网| 免费观看在线综合色| 欧美国产激情二区三区| 欧美激情综合色| 国产精品日韩在线| 国产精品网站在线观看| 欧美一级视频免费在线观看| 一区二区毛片| 国产女优一区| 久久亚洲一区二区| 欧美国产综合一区二区| 亚洲午夜精品网| 欧美亚洲色图校园春色| 亚洲国产精品久久久| 亚洲人成毛片在线播放| 国产精品一区二区三区免费观看 | 亚洲人被黑人高潮完整版| 欧美日韩视频在线第一区| 欧美永久精品| 国产精品毛片a∨一区二区三区| 国产日韩欧美精品在线| 亚洲精品欧美在线| 牛牛国产精品| 狠狠色伊人亚洲综合成人| 99精品视频免费观看| 国产亚洲欧美日韩一区二区| 在线成人欧美| 欧美在线不卡| 亚洲午夜精品久久| 欧美日韩高清在线观看| 亚洲区中文字幕| 亚洲第一综合天堂另类专| 久久免费视频观看| 亚洲电影免费观看高清| 久久精品国产欧美激情| 亚洲视频电影图片偷拍一区| 欧美日韩日本视频| 亚洲欧美日韩天堂| 国产欧美一区二区三区沐欲| 亚洲欧美另类在线观看| 一区二区三区日韩精品视频| 欧美日韩裸体免费视频| 亚洲在线一区| 精品福利电影| 亚洲人成亚洲人成在线观看| 欧美日韩国产欧美日美国产精品| 一区二区三区www| 亚洲理伦电影| 国产精品夜夜夜| 久久精品视频99| 久久精品日韩| 亚洲一区二区三区高清 | 亚洲三级视频| 国产亚洲精品aa午夜观看| 浪潮色综合久久天堂| 欧美成人69| 欧美在线免费观看| 欧美阿v一级看视频| 久久精品夜色噜噜亚洲a∨ | 欧美91视频| 久久精品人人爽| 国产精品美女久久久| 亚洲人成网站777色婷婷| 国产酒店精品激情| 一区二区欧美在线观看| 亚洲精品久久嫩草网站秘色| 在线视频你懂得一区二区三区| 午夜一区在线| 免费观看成人网| 欧美一区二区三区视频在线 | 亚洲精品视频在线| 在线日韩日本国产亚洲| 午夜欧美大片免费观看| 一区二区免费在线视频| 男同欧美伦乱| 亚洲第一在线| 亚洲美女网站| 欧美精品久久久久久| 亚洲人人精品| 亚洲视频1区2区| 国产精品美女在线观看| 欧美图区在线视频| 亚洲图片欧美午夜| 国产精品久久久久久久午夜| 99国产精品99久久久久久粉嫩| 亚洲视频1区|