SVX日記
2016-10-04(Tue) sdccのcharがunsignedになっててドハマり物語
ラズベリーパイとPIC間でI2C通信を成立させたくて、PIC用にI2Cスレーブのスタックを、純ソフトウェア実装で書いていたのだが、スレーブとしてとりあえずの受信に成功したところで、ライブラリ化するため、コードを分割しようとしたところ、これがどうにも動かなくなってしまった。
生成されたアセンブラコードに降りていくと、確かに符号付きとして数値比較しているらしきコードが見当たらない。すわコンパイラのバグか!?と、思って「sdcc signed char」でググってみたところ、charはunsignedとして扱われる旨の情報がある。ウッソ!? いつからッ!?
News
June 12th, 2016: Small Device C Compiler 3.6.0 released.
SDCC 3.6.0 Feature List:
char type is now unsiged by default (old behaviour can be restored using --fsigned-char)
$ cat test.c
#include <stdio.h>
void main() {
char x = -1;
signed char sx = -1;
unsigned char ux = -1;
printf(" %lu %x\n", sizeof(x), (unsigned char)x);
printf("s %lu %x\n", sizeof(sx), (unsigned char)sx);
printf("u %lu %x\n", sizeof(sx), (unsigned char)ux);
printf(" %x\n", x > 0);
printf("s %x\n", sx > 0);
printf("u %x\n", ux > 0);
}
$ ./a.out
1 ff
s 1 ff
u 1 ff
0
s 0
u 1
「0, 1, stop condition」の3値を返す関数だったので、オシャレに負数を返すように変更したことが裏目に出た。しかし、char型がデフォルトでunsignedなんてCの仕様として許されないんじゃねーのか? と、K&Rの第2版をパラパラ……「このcharが符合付きか符合なしかは機種によるが……」なんですか、そーでしたか……私が悪うござんした。
--fsigned-char
By default char is unsigned.
To set the signess for characters to signed, use the option --fsigned-char.
If this option is set and no signedness keyword (unsigned/signed) is given, a char will be unsigned.
All other types are unaffected.
--funsigned-char
The default signedness for every type is signed.
In some embedded environments the default signedness of char is unsigned.
To set the signess for characters to unsigned, use the option --funsigned-char.
If this option is set and no signedness keyword (unsigned/signed) is given, a char will be signed.
All other types are unaffected.