これは機能します:
const int size = 2; int array[size] = {0};
これにはコンパイルエラーがあります:
int a = 2; const int size = a; int array[size] = {0};
なぜ?
C++ 委員会のメンバーがそう決めたからです。
技術的な理由は、初期化に使用される最初の式がsize
定数式であり、コンパイル中に計算できるためです。これは、コンパイラが配列がどのくらいの大きさになるかを知ることができ、割り当て (この場合は「予約」がより適切な用語かもしれません) をコンパイル時に行うことができることを意味します。
2 番目のケースでは、代わりに式が定数式ではなく (C++ の定義が与えられている場合)、この元に戻すことはできません。
2 番目のケースでは、値が初期化されるまでに実際に固定されているという事実は、size
まったく無関係です。ルールは「式の種類」に基づいており、2 番目の式は変更可能な変数を使用するため、コンパイラはそれを非定数と見なします。
コンパイル時の初期化に 2 番目の形式を許可するには、フロー分析が必要になります。
int a = 2;
const int size = a;
と
int a = foo();
const int size = a;
ここで、関与する式size
は実際に同一です。
const int size = 2;
int array[size] = {0};
ここで2
は、リテラル値です。つまり、変更することはできず、コンパイラはコンパイル時に値を認識しています。
int a = 2;
const int size = a;
int array[size] = {0};
ただし、a
は変数です。つまり、値a
が変更される可能性があり、実行時に確実に変更されるため、コンパイラは禁止します。使用できます
int a = 2;
int size = a;
int* array = new int[size];
したがって、動的サイズの配列を申請できます。
メモリ管理についてです。
C++ の性質上、OS がプログラムを実行しようとすると、OS はスタック領域の正確なスペースを知りたがります。最初の例では、OS は変数の値が変更されないことを認識します。しかし、OS のビューでの 2 番目の例では、「a」である最初の変数は次の間で変更できます。
int a = 2;
これとこれ
const int size = a;
変数 a は変更可能です。これが、コンパイラがコードのコンパイルを許可しない理由です。
メモリ管理の基本について詳しく学ぶため。https://stackoverflow.com/a/24922/2326288このコメントをお勧めします 。
最初のケースでsize
は、コンパイル時にコンパイラによって初期化されるためです。2 番目のケースでは、実行時に初期化されるa
可能性があるため、実行時にも初期化され、コンパイル時の定数ではなくなります。size