[2374] Re:ポインタ完全制覇の質問
投稿者:(ぱ)こと管理人
2024/05/15 22:20:25
>①前回ご教示頂いた内容の私なりの解釈では、グローバル変数などの静的変数は初期化しなかった場合、
> 算術型の変数は0で初期化されると理解しました。
> であれば、int a[]も関数外で宣言することにより、プログラマが初期化しなくてもグローバル変数
> として自動的に初期化され、JIS X 3010:2003「6.7.8 初期化」のc)d)の合わせ技により、配列内に
> 少なくとも一つは0が代入され、int a[] = {0};と同義になるのではと思い、関数外であればint a[];
> を宣言できるのではと考え、試しに関数外に宣言してみたのですがコンパイルエラーになりました。
> 前述【超重要!!】の内容はやはり正しいとして、今回私が疑問に思い行った実験は初期化の考え方が
> 間違っているのでしょうか?
初期化とは関係なく、配列にはサイズが必要です。
サイズを入れない空の[]が書ける場所は、「ポインタ完全制覇」なら「3-5-3 空の[]について」で
説明している以下の箇所です。
1.関数の仮引数の宣言
2.初期化子により配列のサイズが確定できる場合
3.グローバル変数をextern宣言する場合
ここで、1はポインタに読みかえられるのでそもそも配列ではなく、
2と3は、初期化子でサイズがわかったり、別のコンパイル単位にサイズが書いてあることが
期待できる、という理由で空の[]が書けます。
extern宣言ではないグローバル変数の定義で、初期化子も書かなければ、
やはりサイズは必要です。
関数外に、単に
int a[];
と書いて、仮にコンパイルが通ったとして、この配列の要素数はいくつであるのが適当でしょうか?
「少なくとも一つは0が代入され、int a[] = {0};と同義」になったとしても、
別に便利でもないのではないでしょうか。
>②①のあとに、グローバル変数であることが重要なのではなく静的変数であることが重要なのではと考え、
> 試しにstatic int a[];としたら、これはコンパイルが成功しました。
これは普通にコンパイルが通らないのでは、と思います。
私がgcc 9.4.0で試したところ、
関数外にstatic int a[];と書いたら以下のエラーが出ました。
test.c:3:12: warning: array ‘a’ assumed to have one element
3 | static int a[];
関数内だと以下です。いずれにしてもエラーです。
test.c:6:16: error: storage size of ‘a’ isn’t known
6 | static int a[];
sasakiさんの環境でエラーにならないようでしたら、環境(OS, コンパイラ、コンパイラのバージョン)を
教えてください。また、ソースをまるごとここに貼ってください。