web-dev-qa-db-ja.com

Cのファイルスコープで可変的に変更された配列

このようなコードがいくつかあります:

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」

これはどうして起こるのでしょうか?どうすれば修正できますか?

28
user707549

サイズが変数として指定されている静的配列を持つことはできません

それが定数が#definedであるべき理由です:

#define a 6

このようにして、プリプロセッサはa6で置き換え、有効な宣言にします。

45
zch

簡単な答え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およびbconstとして作成しても役に立ちませんが、C++constで正常に動作します。

9
Omkant

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は読み取り専用として解釈されます)

このスレッドの説明を参照してください。

「Initializer要素は定数ではありません」というエラーがLinux GCCで理由もなく、Cをコンパイルする

1
PolarBear2015