web-dev-qa-db-ja.com

sizeof(空の構造体)とsizeof(空の配列を持つ構造体)の違いは?

次のように定義された2つの構造体があります。

_struct EmptyStruct{

};

struct StructEmptyArr{
    int arr[0];
};

int main(void){
    printf("sizeof(EmptyStruct) = %ld\n", sizeof(EmptyStruct));
    printf("sizeof(StructEmptyArr) = %ld\n", sizeof(StructEmptyArr));

    return 0;
}
_

Ubuntu 14.04、x64でgcc(g ++)4.8.4を使用してコンパイル。

出力(gccとg ++の両方):

_sizeof(EmptyStruct) = 1
sizeof(StructEmptyArr) = 0
_

sizeof(EmptyStruct)が_1_と等しい理由は理解できますが、sizeof(StructEmptyArr)が_0_と等しい理由は理解できません。 2つの間に違いがあるのはなぜですか?

35
duong_dajgja

Cでは、構造体が名前付きメンバーなしで定義されている場合、プログラムの動作は未定義です。

C11-§6.7.2.1:

Struct-declaration-listに名前付きメンバーが含まれていない場合、直接、または匿名構造または匿名ユニオンを介して、動作は未定義です。

GCCは空の構造体を 拡張 として許可し、そのサイズは_0_になります。


C++の場合、 標準ではサイズ_0_ のオブジェクトは許可されないため、sizof(EmptyStruct)は値1を返します。
長さ0の配列は標準C++¹ではサポートされていませんが、 GNUによる拡張としてサポートされています であり、sizeof演算子は_0_を返します適用される場合。


1.§8.5.1-footnote 107)C++には長さゼロの配列はありません。

40
haccks

https://gcc.gnu.org/onlinedocs/gcc/Empty-Structures.html

G ++は、空の構造体をchar型の単一のメンバーがあるかのように扱います。

https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

GNU Cでは長さゼロの配列を使用できます。これらは、実際には可変長オブジェクトのヘッダーである構造体の最後の要素として非常に役立ちます。

5
user5368518