web-dev-qa-db-ja.com

アクセス時に「不完全な型へのポインタの添え字」を出力する可変2次元配列

私は2次元配列をそのように宣言しています:

char arr[10][10];
arr[0][0] = 'X';

今、私はデバッガーで印刷します。

(lldb) po arr[0][0]
'X'

驚くばかり!!問題ない。

今、私は2次元配列をそのように宣言しています:

int col = 10;
int row = 10;
char arr[row][col];
arr[0][0] = 'X';

今、私はデバッガーで印刷します。

(lldb) po arr[0][0]
error: subscript of pointer to incomplete type 'char []'
error: 1 errors parsing expression

なぜ??

21
etayluz

デバッガーは配列の大きさを正確に認識していないため、キャストを適用する必要があります。

(gdb) p ((char (*)[10])arr)[0][0]
$2 = 88 'X'
17
dbush

だからdbushは正しい。しかし、これが理由です。もう少し詳しく説明します。

char arr[10][10];

と同じものではありません

char arr[row][col];

見た目も動作も似ていますが。

C89標準では、コンパイラが変数に割り当てるスペースの量がわからないため、2番目は違法です(前の2行で定義されていても)。

C99標準を入力すると、可変長配列と呼ばれるものが導入されました。配列のスペース割り当ては、コンパイル時ではなく実行時で決定されます。これで、いくつかの変数を関数に渡し、それらの変数に基づいたサイズの配列を宣言できます。わーい!

しかし、それはコンパイラが配列についての詳細を公式に知らないことを意味します。それがどれほど大きいかのように。また、LLDBはClang/LLVMコンパイラを使用してコードを理解します。

これは、言語が少し高いレベルになり、内部で行う作業を抽象化する例です。そして時々それはお尻にあなたを噛みます。

14
Philip

colrowをconstにします

const int col = 10; const int row = 10;

2
Liu Hao