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

Prayer

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

64bit需要做的改變

Posted on 2009-10-09 09:29 Prayer 閱讀(974) 評論(0)  編輯 收藏 引用 所屬分類: C/C++LINUX/UNIX/AIX
最近64bit以更低的代價開放到了廣大的用戶面前,對于需要更大的內存空間,或者更精確的浮點數計算的開發者來說,無疑提供了更多的方便。這篇文章的目的是要讀者了解對于32bit的源代碼向64bit轉移所要做的工作。

事實上來說,32bit的代碼可以很方便的移植到64位機上,因為64位提供了對32位很好的支持,只有在你有以下的需要的時候,嘗試去修改你的代碼

  • 獲得超過4GB內存的支持。
  • 獲得超過2G大小文件的支持
  • 獲得更精確的浮點數運算
  • 獲得64位機優化的數學運算庫

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

    1。ILP32和LP64 數據模式

    大多數unix系統的數據模式是采用LP64bit的,long和pointer是8個字節64位的,相對于32bit的4個字節。將來windows或許會采用一種數據模式LLP64,只是對于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的錯誤都是來自誤以為int long pointer都是64bit的,實際則不然。下面是一個程序演示了這個錯誤。

    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      }
    上面的代碼是錯誤的,需要進行修正。

    移植的第一項工作,是讓編譯器能檢測到64位的錯誤。這根據編譯器的不同而變化。對于IBM的XL 編譯器家族來說,有用的參數是-qwarn64 -qinfo=pro. 把你的代碼編譯成64bit需要加上-q64,對于gcc編譯器來說則是加上-m64,下面列舉一些編譯64位一些有用的gcc參數。

    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 *.

    下面演示以下編譯上面代碼所出現的提示信息。

    %  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。缺少原型的轉換方面的考慮

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

    會出現錯誤的,32位的int要轉換成64位會出現錯誤的,要避免這種錯誤,include正確的頭文件<unistd.h>,里面有getlogin()的原型。

    3。制定數據格式的錯誤

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

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

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

    4.賦值的錯誤

    myint = mylong;
    錯誤出現在64位的值賦給32位的

    5.數值參數的傳輸錯誤

    myptr = myfunc(mylong);會出現傳遞時的轉換類型錯誤

    6.類型強制轉換出現的錯誤

    myint = (int)mylong;

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

    7.更多的微妙的錯誤

    編譯器會發現大多數的潛在的類型轉換方面的錯誤,但是你不能僅僅依賴于編譯器。

    #define INVALID_POINTER_VALUE 0xFFFFFFFF
    在32位上上面的宏定義會被經常地用來測試-1,但是在64位機上,這個數值卻不是-1,而是4294967295。在64位機上-1是0xFFFFFFFFFFFFFFFF。要避免這個錯誤,利用const來聲明,并指定signed還是unsigned

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

    還有就是32位機上的代碼如下

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

    實際上在64位上是不對的。

    8.signed和unsigned的錯誤

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

    k = i +  j;

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

    k = i + (int)j;

    9.union的錯誤


    下面是一個很常見的結構體:

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

    10.big endian和little endian導致的錯誤

    在32位機上的代碼有些移植到64位機上出現錯誤與否還和機器的big endian或者little endian有關。比如下面的代碼。

    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機上編譯不會出現錯誤,因為long 和pointer都是32bit,但是在64位機上不然,盡管如此,如果在little endian的64位機上編譯的話,仍然會得到正確的2,但是在big endian的情況下,則會得到0。

    如果有疑問的話,下面詳細解釋一下。

    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位機上性能的降低

    這個問題是由于64位機的數據結構的膨脹,對于內存需要的增加,以及存儲空間的增加所致。要減少這方面的損失,你可以精心改變你的數據結構中變量定義的順序。比如下面的例子


     
    12.如何測試你的64位代碼

    定義一些宏來完成目標,下面是示例:

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

    13.64位文件和32位文件之間的彼此讀取問題

    #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為對同一個文件的操作過程中工作。要fix這個錯誤,可以設置宏定義,以在64位機上對foo聲明為int32_t。要注意這個細節。

    14.fortran和c語言混合的問題

    下面兩個程序演示了這個錯誤

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

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

    要避免這個錯誤,需要在fortran語言中把i聲明為INTEGER*8,這相當于64位的long.

    最后,結論:64位機提供了對于更多的計算方面的更好的支持,盡管32位代碼一般來說可以移植的很好,但是,得注意這些細節方面的問題,這樣才能使你的代碼一直工作更順利。

    文章來源于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>
            你懂的视频欧美| 黄色一区二区在线观看| 欧美一级片一区| 久久精品72免费观看| 久久精品国产清高在天天线| 久久久综合免费视频| 欧美成人免费视频| 欧美日韩中文| 国产在线欧美| 99精品国产一区二区青青牛奶| 亚洲影院免费观看| 久久综合九色综合欧美狠狠| 91久久久亚洲精品| 中日韩高清电影网| 欧美中文字幕在线播放| 欧美激情视频一区二区三区在线播放 | 日韩视频国产视频| 亚洲专区一区| 久久综合久久综合久久综合| 欧美日韩国产综合在线| 国产日韩精品一区二区| 亚洲国产成人一区| 欧美一区二区免费观在线| 欧美高清一区二区| 亚洲专区一区| 欧美日韩免费观看一区三区| 黑人操亚洲美女惩罚| 在线综合亚洲| 欧美成人午夜激情视频| 中文欧美日韩| 免费一级欧美在线大片| 国产三级精品三级| 夜夜嗨av一区二区三区四季av | 日韩网站在线观看| 久久久久久成人| 中文在线资源观看网站视频免费不卡 | 亚洲一区二区三区精品在线| 免费成人网www| 国产欧美日韩一区| 在线综合亚洲欧美在线视频| 欧美国产一区二区三区激情无套| 欧美一级二级三级蜜桃| 欧美色图麻豆| 一区二区欧美激情| 亚洲高清不卡av| 久久综合狠狠综合久久综合88| 国产深夜精品| 欧美亚洲系列| 亚洲一区二三| 国产精品乱码人人做人人爱| 亚洲午夜精品| aa级大片欧美| 欧美视频日韩视频在线观看| 在线综合亚洲欧美在线视频| 日韩视频在线观看国产| 欧美绝品在线观看成人午夜影视| 亚洲高清久久久| 欧美激情视频免费观看| 玖玖玖国产精品| 亚洲高清在线| 亚洲国产福利在线| 欧美激情精品久久久久久变态| 亚洲国产精品久久久久久女王| 国产精品99久久久久久有的能看| 精品999日本| 麻豆精品传媒视频| 麻豆freexxxx性91精品| 亚洲国产第一页| 欧美激情视频一区二区三区在线播放 | 欧美日本免费| 亚洲香蕉成视频在线观看| 亚洲午夜激情网页| 国产午夜精品全部视频播放| 久久一二三四| 欧美大色视频| 亚洲欧美一区二区精品久久久| 亚洲综合色丁香婷婷六月图片| 国产精品影片在线观看| 久久久久在线观看| 美女精品一区| 亚洲一区亚洲| 久久久久久久激情视频| av成人免费观看| 午夜宅男欧美| 91久久久亚洲精品| 中文精品在线| 亚洲电影有码| 一区二区三区 在线观看视| 国产真实乱偷精品视频免| 欧美激情精品久久久久久黑人| 欧美日韩精品免费观看视频| 性18欧美另类| 欧美ed2k| 欧美一区二区三区喷汁尤物| 噜噜噜噜噜久久久久久91| 亚洲一区三区视频在线观看 | 99国产精品久久| 有坂深雪在线一区| 日韩视频一区二区三区在线播放免费观看 | 欧美日韩三级电影在线| 久久久www成人免费精品| 欧美激情1区2区| 久久久999| 国产精品高清一区二区三区| 欧美aⅴ99久久黑人专区| 国产精品成人播放| 亚洲福利视频二区| 国产一区二区三区四区在线观看| 亚洲人成高清| 亚洲第一区在线观看| 亚洲主播在线| 亚洲影院在线| 欧美福利一区| 裸体丰满少妇做受久久99精品| 国产精品久久久久免费a∨大胸| 亚洲第一成人在线| 伊大人香蕉综合8在线视| 午夜精品国产更新| 一本一本久久| 久久蜜桃av一区精品变态类天堂| 亚洲黄色大片| 在线观看三级视频欧美| 亚洲国产毛片完整版| 亚洲激情精品| 夜夜爽av福利精品导航| 欧美一区二区三区在| 免费观看成人网| 久久免费高清视频| 亚洲嫩草精品久久| 欧美日韩亚洲一区二区三区在线观看 | 亚洲国产精品欧美一二99| 亚洲免费高清视频| 亚洲精品字幕| 欧美一区永久视频免费观看| 免费在线播放第一区高清av| 国产一区二区三区在线免费观看| 久久色在线播放| 美女999久久久精品视频| 欧美高清在线观看| 欧美中文字幕不卡| 亚洲视频免费看| 亚洲色图自拍| 亚洲永久精品大片| 亚洲电影免费在线观看| 亚洲国产电影| 午夜精品一区二区在线观看| 国产欧美一区二区视频| 日韩视频在线免费观看| 欧美激情亚洲视频| 玖玖综合伊人| 久久亚洲综合网| 亚洲高清123| 久久精品国产精品亚洲| 欧美在线观看天堂一区二区三区| 国产精品美女主播| 99国产精品私拍| 久久国产精品久久精品国产| 日韩一级片网址| 国产主播在线一区| 亚洲日本欧美天堂| 亚洲精品欧洲| 国产欧美综合在线| 国产精品美女久久久久久久| 久久精精品视频| 欧美一区二区女人| 国产精品久久久久一区二区三区 | 亚洲视频一二| 狠狠色综合日日| 欧美一区免费视频| 99精品久久免费看蜜臀剧情介绍| 欧美性大战xxxxx久久久| 亚洲免费中文| 亚洲人成网站影音先锋播放| 模特精品裸拍一区| 亚洲国产精品一区二区第一页 | 国产网站欧美日韩免费精品在线观看 | 亚洲午夜久久久久久久久电影网| 国产精品卡一卡二卡三| 亚洲国产成人一区| 在线观看精品一区| 欧美国产日本韩| 欧美夫妇交换俱乐部在线观看| 久久久国际精品| 久久精品国产在热久久| 亚洲一区bb| 亚洲韩日在线| 香蕉成人伊视频在线观看 | 一区二区三区欧美成人| 国产日韩欧美综合| 老鸭窝毛片一区二区三区| 亚洲高清一二三区| 欧美二区在线播放| 亚洲成色777777女色窝| 亚洲国产高清一区| 欧美一区二区视频在线观看| 国产精品你懂的在线欣赏| 亚洲一区二区毛片| 亚洲免费观看| 老司机午夜精品视频| 性欧美1819sex性高清|