ARM gcc では,char 型で宣言した変数は unsinged char として扱われます. x86 などの他の gcc では signed char として扱われます. 普通はこちらの方ですね.
あれだけ散々ARM向けにクロスコパイルしてたのに、今まで知りませんでした。。。ある程度動けば良い方式だしなー^^;
実際にやってみる。
main() { char c1 = 0xff, c2 = 0x01; if ( c1 > c2 ) puts( "0xff > 0x01"); else puts("0xff <= 0x01"); }
% gcc test.c ; a.out
0xff <= 0x01
0xff = -1と思われていることが分かります。
同じことをLS-GL上でやると、
% gcc test.c -o a ; ./a 0xff > 0x01
という結果に。0xff = 255なんですねえ。
オプションをつければ、signedにすることもできる。
% gcc test.c -fsigned-char -o b ; ./b 0xff <= 0x01
大分使い慣れたと思っていたarmなgccで今更だったので、ちょっと目から鱗でした。
何がそんなに違うのだろうと思って、ちょっとディスアセンブルして調べてみましたが、単に命令がsignedっぽいものに変わってるだけ。歴史的経緯とかなのでしょうか?
% diff <(objdump -S b) <(objdump -S a) 2c2 < a: file format elf32-littlearm --- > b: file format elf32-littlearm 117,118c117,118 < 8400: e55b200d ldrb r2, [fp, #-13] < 8404: e55b300e ldrb r3, [fp, #-14] --- > 8400: e15b20dd ldrsb r2, [fp, #-13] > 8404: e15b30de ldrsb r3, [fp, #-14] 120c120 < 840c: 9a000002 bls 841c <main+0x3c> --- > 840c: da000002 ble 841c <main+0x3c>