ARMのgccのcharはunsigned

ARM gcc バッドノウハウ集 : char 型より:

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");
}

母艦のMac/PowerPCだと、

% 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>