2019/01/30

[c/c++][CERT]配列の初期化子サイズ違いでgcc警告を出したいなら-W

C言語再履修シリーズ。

しばらくサボってしまった。。
後回しにしてしまいがちなのがいかんのだろう。


ARR02-C. 初期化子が暗黙的にサイズを定義する場合であっても、配列のサイズは明示的に指定する


あー、そうよねー。
でもまあ、そんなに「すべし」ってほどのものでもないよね?
ん?


要素指示子を一つだけ使うことで、配列の両端に初期値を与えることができる。

要素指示子?
聞いたことがないし、C言語クイックリファレンスの目次にも出てこなかった。

原文では、

Space can be "allocated" from both ends of an array by using a single designator:

となっているので「using a single designator」が「要素指示子を1つだけ使う」だろう。
designatorは「指名者」とか「指定者」という意味なので、まあ、要素指示子なのだろう。

C言語クイックリファレンスでは「配列指示子(array designator)」となっていた。
が、本文を読んでも見つからない。。。

gccでやってみるべし。


01: #include <stdio.h>
02: 
03: #define MAX (10)
04: 
05: int main(void)
06: {
07:     int a[MAX] = {
08:       1, 3, 5, 7, 9, [MAX-5] = 8, 6, 4, 2, 0
09:     };
10: 
11:     for (size_t lp = 0; lp < sizeof(a) / sizeof(a[0]); lp++) {
12:         printf("[%ld] %d\n", lp, a[lp]);
13:     }
14: 
15:     return 0;
16: }

結果

[0] 1
[1] 3
[2] 5
[3] 7
[4] 9
[5] 8
[6] 6
[7] 4
[8] 2
[9] 0


MAXを10→11に変更


結果

[0] 1
[1] 3
[2] 5
[3] 7
[4] 9
[5] 0
[6] 8
[7] 6
[8] 4
[9] 2
[10] 0


なるほど、配列指示子というのは、要素の初期値を添字のどこに置くかを決めるやり方のようだ。
[MAX-5]だから、最初の例では[5]に8が入ったのだが、次の例では[6]に8が入り、[5]が空きになったので0が代入されたということか。



なお、MAXを10より小さくすると、順番が後のデータによって上書きしていくらしい。

MAX=6

結果

[0] 1
[1] 8
[2] 6
[3] 4
[4] 2
[5] 0

ふーん。


コンパイルを gcc -Wallでやったのだけど、警告も何も出ない。
gcc -Wにすると「initialized field overwritten 」の警告が出た。
"-Wall"って、名前詐欺みたいな気がしてしまうのは私だけか。。。

g++の場合は、オプション無しでコンパイルエラーになった。

array_designator.c: In function ‘int main()’:
array_designator.c:9:5: sorry, unimplemented: non-trivial designated initializers not supported
      };
      ^
array_designator.c:9:5: error: too many initializers for ‘int [6]’

gccでもこれくらいやってくれてよいと思う。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。