初期化子の周りに中括弧がないGCC

2012年07月19日に質問されました。  ·  閲覧回数 50.1k回  ·  ソース

fred basset picture
2012年07月19日

以下のCに、すべてゼロに初期化するこの構造体があります。 中括弧の欠落の警告を取り除くにはどうすればよいですか?

typedef struct {
    uint32_t incoming[FRAME_TYPE_MAX];
    uint32_t outgoing[FRAME_TYPE_MAX];
    uint32_t timeouts;
    uint32_t crc_errors;
} pkt_t;

static pkt_t stats = {0};

回答

R.. GitHub STOP HELPING ICE picture
2012年07月19日
40

これはGCCバグ#53119です:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119

修正を確認したい場合は、バグレポートにフォローアップを投稿して、問題があることを示してください。

Josh Petitt picture
2012年07月19日
27

構造体の最初のメンバーは配列であるため、次のものが必要です。

static pkt_t stats = {{0}};

外側の中括弧は構造体用で、内側の中括弧は配列用です。 ただし、この猫の皮を剥ぐ方法は他にもたくさんあります。 (たとえば、静力学はすでにゼロに初期化されています)

Karoly Horvath picture
2012年07月19日
7

グローバル変数またはローカル静的変数の場合、自動的に初期化されます。 だから、簡単に:

static pkt_t stats;
Antimony picture
2012年07月19日
4

1つの方法は、暗黙のゼロ塗りつぶしに依存するのではなく、中括弧内の構造体のすべてのメンバーを初期化することです。 配列メンバーの場合、警告を引き起こしている可能性のある別の{}が必要です。 もう1つは、警告を無効にすることですが、正当なバグを検出する可能性があるため、これはお勧めしません。

Doug Null picture
2015年10月03日
1

このgccコンパイラフラグを設定します:-Wno-missing-braces

Seth Robertson picture
2012年07月19日
0

「infogcc」より

GNU拡張として、GCCは、複合リテラルによる静的ストレージ期間のオブジェクトの初期化を許可します(初期化子は定数ではないため、ISO C99では不可能です)。 複合リテラルとオブジェクトのタイプが一致する場合、オブジェクトは角かっこで囲まれたリストでのみ初期化されたかのように処理されます。 複合リテラルの初期化子リストは定数でなければなりません。 初期化されるオブジェクトの配列タイプが不明なサイズの場合、サイズは複合リテラルサイズによって決定されます。

 static struct foo x = (struct foo) {1, 'a', 'b'};
 static int y[] = (int []) {1, 2, 3};
 static int z[] = (int [3]) {1};

上記の行は、次の行と同等です。

 static struct foo x = {1, 'a', 'b'};
 static int y[] = {1, 2, 3};
 static int z[] = {1, 0, 0};

これらの初期化子を組み合わせて、配列内のすべての要素を指定しなくても、配列のgcc固有の初期化を可能にすることができる場合があります。 または...フラグを設定し、必要に応じて実行時に初期化するか、または...変数がBSSにあり、自動的にゼロになるかどうかを確認できます(これは関数のスタックまたはグローバルメモリにあります) )。

jarjan13 picture
2016年11月18日
0
#define FRAME_TYPE_MAX 3

typedef struct {
    uint32_t incoming[FRAME_TYPE_MAX];
    uint32_t outgoing[FRAME_TYPE_MAX];
    uint32_t timeouts;
    uint32_t crc_errors;
} pkt_t;

static pkt_t stats1= { .incoming={5,6,20},
                       .outgoing={0,0,0},
                       .timeouts=0,
                       .crc_errors=0
                       };

static pkt_t stats2= { {5,6,20},
                       {0,0,0},
                       0,
                       0
                       };

static pkt_t stats3= {{0}};

pkt_t stats4 ;   // global


int main(void)
{

    stats1.incoming[0]= 35;
    stats1.timeouts=25;
    stats2.incoming[2]=10;  
    stats3.outgoing[2]=10;  
    stats4.timeouts=10;
    for (;;);
    }
István Siroki picture
2017年10月16日
0

この誤った警告を省略したgccバージョンを使用することに喜びがある場合は、質問にこのような構造体を使用すると、次のような単純な再構築でこの問題を回避できます。

typedef struct {
    uint32_t timeouts;
    uint32_t crc_errors;
    uint32_t incoming[FRAME_TYPE_MAX];
    uint32_t outgoing[FRAME_TYPE_MAX];
} pkt_t;

static pkt_t stats = {0};