web-dev-qa-db-ja.com

サイズ0の配列

今日、偶然に1次元のサイズが0である2次元配列を定義しましたが、コンパイラーは文句を言いませんでした。少なくともgccの場合、これは合法であると述べている次のことがわかりました。

6.17長さがゼロの配列

ただし、この使用法について2つの質問があります。

まず、これは優れたプログラミング手法と見なされますか?もしそうなら、それを実際の世界でいつ使うべきですか?

次に、私が定義した配列は2次元で、1次元のサイズは0でした。これは1次元の場合と同じですか?例えば、

int s[0]
int s[0][100]
int s[100][0]

それらはすべてメモリとコンパイラで同じですか?

編集:Gregへの返信:私が使用しているコンパイラはgcc 4.4.5です。この問題に対する私の意図はコンパイラーに依存していませんが、役立つコンパイラー固有の癖がある場合:)

前もって感謝します!

35
zw324

C++では、長さ0の配列を宣言することはできません。そのため、コードを特定のコンパイラー拡張に結び付けているため、通常、これは良い方法とは見なされません。動的サイズの配列の多くの使用法は、std::vectorなどのコンテナークラスに置き換える方が適切です。

ISO/IEC 14882:2003 8.3.4/1:

定数式(5.19)が存在する場合、それは整数定数式であり、その値はゼロより大きくなければなりません。

ただし、new[]を使用すると、長さがゼロの配列を動的に割り当てることができます。

ISO/IEC 14882:2003 5.3.4/6:

direct-new-declaratorの式は、負でない値を持つ整数型または列挙型(3.9.1)でなければなりません。

32
CB Bailey

このプログラムは ideone.com で実行しました

#include <iostream>

int main()
{
    int a[0];
    int b[0][100];
    int c[100][0];

    std::cout << "sizeof(a) = " << sizeof(a) << std::endl;
    std::cout << "sizeof(b) = " << sizeof(b) << std::endl;
    std::cout << "sizeof(c) = " << sizeof(c) << std::endl;

    return 0;
}

すべての変数のサイズは0でした。

sizeof(a) = 0
sizeof(b) = 0
sizeof(c) = 0

したがって、上記の例では、ab、またはcにメモリが割り当てられていません。

3
Node

あなたの例をgccでコンパイルすると、3つすべてがsizeof 0になるので、コンパイラーによってそれらすべてが同等に扱われると想定します。

2
Kanopus

あなたのリンクはすべてを説明します。これらは、コンパイル時に構造体の長さがわからない場合に、構造体の最後のフィールドとして使用されます。スタックまたは他の宣言の途中でそれらを使用しようとすると、次の要素が上書きされることになります。

2
Piotr Praszmo