#include <stdio.h>
#include <limits.h>
int main(void)
{
char c = -1;
printf("%d\n", c);
printf("(CHAR_MAX == SCHAR_MAX) = %d\n", CHAR_MAX == SCHAR_MAX);
return 0;
}
をx86
アーキテクチャで実行すると
-1
(CHAR_MAX == SCHAR_MAX) = 1
となりますが、 AArch64
(ARM 64bit) では
255
(CHAR_MAX == SCHAR_MAX) = 0
となります。char
と書いたときに符号有りになるか符号無しになるかでこの違いが生じます。これは未定義動作ではないので -fsanitize=undefined
で捕まえられないし、 -Wall -Wextra
を付けてもコンパイラは教えてくれません…😭
確認は gcc 10.2 と LLVM CLang 11.0 で行いました。
コメント
@SaitoAtsushi1
@fujitanozomuC Dialect Options (Using the GNU Compiler Collection (GCC)) https://gcc.gnu.org
0
@fujitanozomu(編集済み) Compiler Explorer - C https://godbolt.org
0
@kakinaguru_zo
0
@kakinaguru_zo0
オプション
-Wconversion
を付けると警告は出るようです。 (-Wall
や-Wextra
で有効にならない警告はこの他にもたくさんあります。)この程度の (暗黙の) 変換は大抵のプログラムで頻出しますし、その大半は実際に問題ないので常に付けるのはわずらわし過ぎるオプションだと思いますが、問題があったときに怪しい箇所の候補を探すには使えるかもしれません。
gcc や clang であれば signed も unsigned もつかない素の char の符号あり/なしはコンパイラオプションで指定可能で好きな方に設定すれば済む話では?
gcc 11.1 と clang 11.0.1 で確認してみた
それは前から知っています。知ってて書いています @fujitanozomu
記事著者よりも自分のほうがわかっているという思い上がりが感じられるコメント投稿者はブロックします