75151


実行環境は下記の通りです

CPU ryzen 5 3600  
OS windows10 64bit上のvirtual boxでUbuntu 18.04.5 LTSを起動  
コンパイラ clang  
オプション -Werror -Wall -Wextra

[code]

    #include <stdio.h>
    
    int main()
    {
        char c;
        char s[10] = {};
    
        s[0] = 'a';
        c = 0;
        printf("%c\n", s[c]);
    }
    
[/code]

[code]

    array subscript is of type 'char' [-Werror,-Wchar-subscripts]
            printf("%c\n", s[c]);
    
[/code]

以下のようにキャストするか、またはcharではなくint8_t, signed char型で宣言するとコンパイルは通るようになります。

[code]

    s[(signed char)c]
    
[/code]

char型がsignedで定義されている処理系で128以降がオーバーフローする可能性があるためこういった警告が出るようになっていると推測していますが、それを確認するために参照すべきドキュメントが見つけられませんでした。  
私の理解は間違っていますか？また、こういったことを確認したい場合、参照するべきドキュメントがあれば教えていただきたいです。  
よろしくお願いします。


CC BY-SA 4.0
2021-04-07T11:53:12.223
75148
2021-04-07T13:04:42.223
44647
question
c
C言語の配列の添え字[]内をchar型で指定するとコンパイルが通らないのってどうしてですか？


K&R 2nd の 2.2 Data Types and Sizes に

> Whether plain `char`s are signed or unsigned is machine-dependent, but
> printable charactoers are always positive.

と定義されています。つまり、`char`は符号付きの可能性もあるし、符号なしの可能性もある曖昧な型です。文字として扱うのであれば問題ありませんが、数値として扱うのは危険であり、それが警告されています。

[INT07-C. 数値には符号の有無を明示した char 型のみを使用する](https://www.jpcert.or.jp/sc-
rules/c-int07-c.html)で説明されていますが、具体例として

[code]

    char c = 200;
    int i = 1000;
    printf("i/c = %d\n", i/c);
    
[/code]

というコードがあった場合、 `i/c = 5` もしくは `i/c = -17`
どちらの結果にもなり得るわけで、コードとして正しくても、プログラムとしては意味のないものになってしまいます。

`s[(signed char)c]` とするよりは `signed char c;` とすることをお勧めします。


CC BY-SA 4.0
2021-04-07T12:55:58.030
75150
2021-04-07T12:55:58.030
4236
75148
answer


`Clang`のドキュメントはこれでしょう。

> [-Wchar-subscripts - Diagnostic flags in
> Clang](https://clang.llvm.org/docs/DiagnosticsReference.html#wchar-
> subscripts)
[code]

>     Diagnostic text:
>                             lower bound
>     warning: array section ------------- is of type 'char'
>                             length
>     warning: array subscript is of type 'char'
>  
[/code]

他のエラーも含めてソースコードからの機械抽出らしいので、あまり内容は期待できませんね。

[Clang警告オプションとメッセージ一覧](https://yohhoy.hatenadiary.jp/entry/20150718/p1)

> LLVM/Clangコンパイラの警告オプション(-Wxxx)と出力メッセージの対応一覧表。Clangソースコードから機械抽出とのこと。
>
>   * <http://fuckingclangwarnings.com/>
>   * <https://github.com/NSHipster/fuckingclangwarnings.com>
>

* * *

@metropolis さんコメントのように、解説としては`GCC`の方に同じ警告があって記述があります。

[3.8 Options to Request or Suppress
Warnings](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html)

> -Wchar-subscripts  
>  Warn if an array subscript has type char. This is a common cause of error,
> as programmers often forget that this type is signed on some machines. This
> warning is enabled by -Wall.

> 配列の添え字の型がcharの場合に警告します。これはエラーの一般的な原因ですが、プログラマーはこの型が一部のマシンで符号付きであることを忘れがちです。  
>  この警告は -Wallによって有効になります。

`char型がsignedで定義されている処理系で128以降がオーバーフローする可能性があるためこういった警告が出るようになっていると推測しています`

については、範囲外であるという意味では類似していますが、`オーバーフロー`というよりも`アンダーフロー`の方が相応しいと思われます。

この辺の記事から辿りました。  
[Warning: array subscript has type
char](https://stackoverflow.com/q/9972359/9014308)  
[C++ Warning Array Subscript Has Type
'char'](https://stackoverflow.com/q/58793298/9014308)

* * *

この記事によると：  
[[C++] GCC/Clang/VisualStudio
の警告をまとめているので紹介](https://zenn.dev/srz_zumix/articles/4c72e544b0034cc796da)

こちらのリポジトリでコンパイラ横断的にまとめられているようです。  
[srz-zumix/awesome-cpp-warning](https://github.com/srz-zumix/awesome-cpp-
warning)

資料/説明が無ければ他のコンパイラの仕様を参照してみてはどうでしょう？

ただし、類似であろうとの調査結果？/推測？で表になっていると思われるし、変わる可能性も考えられるので、注意はしておいた方が良いでしょうね。


CC BY-SA 4.0
2021-04-07T12:56:01.163
75151
2021-04-07T13:04:42.223
2021-04-07T13:04:42.223
26370
26370
75148
answer