2016年3月2日 星期三

c 語言 - 比較 char c==0xff

不經一事不長一智

還真不知道怎麼寫這個標題, 從程式碼看結果。

d.cpp
 1 #include <stdio.h>
 2 
 3 int main(int argc, char *argv[])
 4 {
 5   char c = 0xff;
 6 
 7   printf("c: %hhx\n", c);
 8   if (c == 0xff)
 9   {
10     printf("yy\n");
11   }
12   else
13   {
14     printf("zz\n");
15   }
16   return 0;
17 }

d.cpp 應該要印出 yy 還是 zz 呢? 答案可能出乎你的意料之外, 回答 yy 或是 zz 的朋友恭喜你們都答對了。

編譯指令
g++ -m32 -o d.x86 d.cpp
arm-linux-gnueabihf-g++ -o d.rpi2 d.cpp


x86 測試結果
descent@debian64:tmp$ g++ -m32 -o d.x86 d.cpp
descent@debian64:tmp$ ./d.x86
c: ff
zz


rpi2 測試結果
raspberrypi:~# g++ -o d.arm d.cpp
raspberrypi:~# ./d.arm
c: ff
yy

怎麼辦? 把 char c = 0xff; 改成 unsigned char c = 0xff; 就可以得到相同結果 yy; 而把 char c = 0xff; 改成 signed char c = 0xff 則會得到相同結果 zz。

以下的 gcc option 也可以做到類似的效果。

man gcc
-fsigned-char
Let the type "char" be signed, like "signed char".

Note that this is equivalent to -fno-unsigned-char, which is the negative form of -funsigned-char. Likewise, the option -fno-signed-char is equivalent to -funsigned-char.

看來還是把 char 的 signed/unsigned 指定好比較保險。

arm 版本的 gcc char 是 unsigned char; x86 版本的 gcc char 是 signed char。

3 則留言:

  1. 感謝大大,又增加了一點知識。

    回覆刪除
  2. 這以前寫DOS程式好像就遇過類似問題
    Turbo/Borland C 也可以預設 char 是 unsigned 或是 signed
    個人偏好用unsigned 因為常常需要處理 raw/binary 跟硬體有關的東西

    回覆刪除
  3. 這個坑很大, 好幾位朋友都踩過。

    回覆刪除

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。