5.2.1 移植過程演示
1.x86架構下運行效果
步驟1:登錄x86架構服務器,進入/data/code/文件夾,創建文件transfer.c,指令如下:
cd /data/code/ vi transfer.c
步驟2:在文件transfer.c中輸入如下代碼:

這段代碼按照預期,應該會打印出a=-1來。
步驟3:編譯transfer.c,指令如下:
gcc -o transfer transfer.c
步驟4:執行transfer,查看輸出結果,指令如下:
./transfer
輸出結果如圖5-5所示。

圖5-5 x86架構輸出結果
可以看出來,打印輸出的結果就是希望看到的-1。
2.鯤鵬架構下運行效果
在鯤鵬架構下同樣編譯并執行。
步驟1:登錄鯤鵬架構服務器,進入/data/code/文件夾,創建文件transfer.c,指令如下:
cd /data/code/ vi transfer.c
步驟2:在文件transfer.c中輸入和x86架構下一樣的代碼,代碼如下:

步驟3:編譯transfer.c,指令如下:
aarch64 - redhat - Linux - gcc -o transfer transfer.c
步驟4:執行transfer,查看輸出結果,指令如下:
./transfer
輸出結果如圖5-6所示。

圖5-6 鯤鵬架構輸出結果
這個結果和預期的結果不一樣,輸出的是255。
3.原因分析
-1的二進制原碼是10000001,它的補碼是除了符號外取反加1,最后補碼就是11111111。在x86架構下,char默認是有符號的,所以打印的時候正常打印-1,但是在鯤鵬架構下char默認是無符號的,這個二進制的11111111正好就是無符號的255。
所以,出現這種情況的原因就是x86架構和鯤鵬架構對于char的默認處理不一樣,一個是默認有符號,另一個是默認無符號。
4.處理方式
對于這種情況,有兩種處理方式,一種是修改源代碼,把數據類型指定為有符號型,另一種就是在編譯時指定參數,把默認無符號型改成默認為有符號型,下面演示說明。
1)修改編譯參數
修改編譯參數比較簡單,只需要在gcc后面加入-fsigned-char編譯選項即可,命令如下:
aarch64 - redhat - Linux - gcc -fsigned-char -o transfer transfer.c
需要注意的是,該選項會把源代碼中所有的char類型變量都當作有符號類型,如果只是更改其中部分char變量,這種方式就不合適了。
修改后的執行效果如圖5-7所示,可以看到得到了期望的輸出。
2)修改源代碼
修改源代碼雖然有點復雜,但靈活性比較高,可以一勞永逸地解決問題,修改方法就是把char類型改成signed char即可。在/data/code/目錄下新建transfer_new.c,然后輸入修改后的代碼:

圖5-7 鯤鵬架構修改編譯參數后的輸出結果

編譯的時候不用指定編譯選項,直接編譯即可,最后執行效果如圖5-8所示,可以看到也得到了期望的輸出。

圖5-8 鯤鵬架構下transfer_new執行輸出結果