このようなコードがいくつかあります:
static int a = 6;
static int b = 3;
static int Hello[a][b] =
{
{ 1,2,3},
{ 1,2,3},
{ 1,2,3},
{ 1,2,3},
{ 1,2,3},
{ 1,2,3}
};
しかし、コンパイルするとエラーが表示されます:
ファイルスコープで可変的に変更された「Hello」
これはどうして起こるのでしょうか?どうすれば修正できますか?
サイズが変数として指定されている静的配列を持つことはできません
それが定数が#define
dであるべき理由です:
#define a 6
このようにして、プリプロセッサはa
を6
で置き換え、有効な宣言にします。
簡単な答えvariable modified array at file scope is not possible
。
詳細:
コンパイル時に配列の長さを指定する必要があるため、コンパイル時にintegral constant expression
にします。
このような :
#define a 6
#define b 3
または、c99標準に従ってください。 gccのようにコンパイルします。
gcc -Wall -std=c99 test.c -o test.out
ここでの問題は、長さが初期化されていない可能性がある可変長配列なので、このエラーが発生することです。
単に
static int a =6;
static int b =3;
void any_func()
{
int Hello [a][b]; // no need of initialization no static array means no file scope.
}
次に、forループまたは任意のループを使用して配列を埋めます。
詳細はデモのみです:
#include <stdio.h>
static int a = 6;
int main()
{
int Hello[a]={1,2,3,4,5,6}; // see here initialization of array Hello it's in function
//scope but still error
return 0;
}
root@Omkant:~/c# clang -std=c99 vararr.c -o vararr
vararr.c:8:11: error: variable-sized object may not be initialized
int Hello[a]={1,2,3,4,5,6};
^
1 error generated.
静的を削除して初期化を行うと、上記のエラーが生成されます。
ただし、初期化と同様に静的なままにすると、まだエラーになります。
ただし、初期化を削除してstatic
を保持すると、次のエラーが発生します。
error: variable length array declaration not allowed at file scope
static int Hello[a];
^ ~
1 error generated.
したがって、可変長配列宣言はファイルスコープで許可されていないため、関数内で関数またはブロックスコープにします(ただし、関数スコープに初期化を削除する必要があることを忘れないでください)
注:C
タグ付けされているので、a
およびb
をconst
として作成しても役に立ちませんが、C++
const
で正常に動作します。
CLANG/LLVMを使用する場合、以下が機能します。
static const int a = 6;
static const int b = 3;
static int Hello[a][b] =
{
{ 1,2,3},
{ 1,2,3},
{ 1,2,3},
{ 1,2,3},
{ 1,2,3},
{ 1,2,3}
};
(生成されたアセンブリで表示するには、Helloを使用して最適化されないようにする必要があります)
ただし、C99モードが選択されている場合(-std = c99)、エラーが生成され、-pedanticが選択されている場合にのみ警告(Wgnu-folding-constant)が生成されます。
GCCはこれを許可していないようです(constは読み取り専用として解釈されます)
このスレッドの説明を参照してください。