web-dev-qa-db-ja.com

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

私のObjective-C実装ファイル全体で使用する定数静的配列を作成して、「。m」ファイルのトップレベルで次のようなものを作成します。

static const int NUM_TYPES = 4;
static int types[NUM_TYPES] = { 
  1,
  2, 
  3, 
  4 };

後でファイルでNUM_TYPESを使用する予定なので、変数に入れたいと思いました。

ただし、これを行うと、エラーが発生します

「ファイルスコープで可変的に変更された「タイプ」」

これは、配列サイズが変数であることに関係している可能性があることを収集します(static int types[4]のような整数リテラルをそこに配置しても、このメッセージは表示されません)。

私はこれを修正したいのですが、多分私はそれについてすべて間違っています...私はここに2つの目標があります:

  1. ファイル全体でアクセス可能な配列を持つ
  2. NUM_TYPESを変数にカプセル化して、ファイル内の異なる場所に散在する同じリテラルを持たないようにする

助言がありますか?

[編集] C FAQでこれを見つけました: http://c-faq.com/ansi/constasconst.html

81
Sam

この警告の理由は、 cの定数は定数を意味しない。「読み取り専用」を意味する 値はメモリアドレスに格納され、マシンコードによって変更される可能性があるためです。

60
larsr

とにかくプリプロセッサを使用する場合は、他の回答に従って、コンパイラにNUM_TYPESの値を自動的に決定させることができます。

#define NUM_TYPES (sizeof types / sizeof types[0])
static int types[] = { 
  1,
  2, 
  3, 
  4 };
32
caf
#define NUM_TYPES 4
21
Jim Buck

列挙を使用することもできます。

typedef enum {
    typeNo1 = 1,
    typeNo2,
    typeNo3,
    typeNo4,
    NumOfTypes = typeNo4
}  TypeOfSomething;
11
Dave L Delaney

他の回答で既に説明されているように、Cのconstは、変数が読み取り専用であることを意味します。まだ実行時の値です。ただし、Cでenumを実定数として使用できます。

enum { NUM_TYPES = 4 };
static int types[NUM_TYPES] = { 
  1, 2, 3, 4
};
3
CygnusX1

これは多くのCコンパイラの欠陥です。私が働いていたコンパイラは、アドレスに「静的const」変数を格納しないが、コードでの使用を非常に定数で置き換えることを知っています。プリプロセッサの#defineディレクティブを使用し、静的なconst変数を使用すると、生成されたコードに対して同じチェックサムを取得するため、これを検証できます。

どちらの場合も、静的constはタイプセーフであるため、可能な限り#definesの代わりに静的const変数を使用する必要があります。

3
hans lepoeter