0
@kakinaguru_zo

ARMのCコンパイラではcharが符号無しだった❣(x86は符号有り)

#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 で行いました。

0
ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます

コメント

オプション -Wconversion を付けると警告は出るようです。 (-Wall-Wextra で有効にならない警告はこの他にもたくさんあります。)

warning: conversion from 'int' to 'char' changes value from '221' to '-35' [-Wconversion]

この程度の (暗黙の) 変換は大抵のプログラムで頻出(ひんしゅつ)しますし、その大半は実際に問題ないので常に付けるのはわずらわし過ぎるオプションだと思いますが、問題があったときに怪しい箇所の候補を探すには使えるかもしれません。

1

確認は gcc 10.2 と LLVM CLang 11.0 で行いました。

gcc や clang であれば signed も unsigned もつかない素の char の符号あり/なしはコンパイラオプションで指定可能で好きな方に設定すれば済む話では?

0

gcc 11.1 と clang 11.0.1 で確認してみた

0

gcc や clang であれば signed も unsigned もつかない素の char の符号あり/なしはコンパイラオプションで指定可能で好きな方に設定すれば済む話では?

それは前から知っています。知ってて書いています @fujitanozomu

0

記事著者よりも自分のほうがわかっているという思い上がりが感じられるコメント投稿者はブロックします

0
あなたもコメントしてみませんか :)
ユーザー登録
すでにアカウントを持っている方はログイン
記事投稿イベント開催中
エンジニアによるマネジメント - エンジニアだからこそ発信できるマネジメントの知識を発信しよう
~
Microsoft Buildで発表された技術情報に関する記事を投稿しよう!
~