12

指定された初期化子を使用するときに、構造体のすべてのフィールドが GCC で初期化されるようにするにはどうすればよいですか? (私は特に関数ポインタに興味があります。) (私は C++ ではなく C を使用しています。)

次に例を示します。

typedef struct {
    int a;
    int b;
} foo_t;

typedef struct {
    void (*Start)(void);
    void (*Stop)(void);
} bar_t;

foo_t fooo = { 
        5 
    };

foo_t food = { 
        .b=4 
    };

bar_t baro = {
        NULL
    };

bar_t bard = { 
        .Start = NULL
    };

-Wmissing-field-initializers はまったく役に立ちません。GCC (mingw 4.7.3、4.8.1) でのみ foo に対して機能し、 clangはわずかに優れているだけです (食品と吟遊詩人に対する警告はありません)。

指定された初期化子の警告を生成しない理由があると確信していますが (明示的に要求した場合でも)、それらが必要/必要です。エラーが発生しやすいため、順序/位置に基づいて構造を初期化したくありません (たとえば、Start と Stop を入れ替えても警告は表示されません)。また、gcc も clang も、フィールドを明示的に初期化できなかったという警告を表示しません (名前で初期化する場合)。また、複数の理由から、コードに if(xy==NULL) 行を散らかしたくありません。その 1 つは、実行時エラーではなくコンパイル時の警告が必要なことです。

少なくともスプリントは 4 つのケースすべてで警告を出しますが、残念ながら常にスプリントを使用することはできません (一部のコードでチョークします (一部の C99、GCC 拡張機能の解析に失敗します))。

注:NULLの代わりに実際の関数を使用している場合、GCCはbaroの警告も表示します(bardではありません)。

Google とスタック オーバーフローを検索しましたが、関連する質問しか見つかりませんでした。この特定の問題に対する回答は見つかりませんでした。私が見つけた最良の一致は、「構造内のすべての要素が初期化されている ことを確認する」です。構造内のすべての要素が初期化されていることを確認してください 。これはほとんど同じ質問をしますが、満足のいく答えはありません。

私が言及していないこれに対処するより良い方法はありますか? (多分他のコード分析ツール? できれば Eclipse や Visual Studio に統合できる何か (無料)...)

4

2 に答える 2

6

私が間違っていなければ、C 標準では、他のフィールドは自動的に 0 で初期化されると規定されています。

したがって、あなたが求めているもの - フィールドが初期化されていない場合のコンパイルエラー - は、C (現代の?) 仕様と一致しません。

C99 標準、127 ページ: http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf

集合体の要素またはメンバーよりもブレースで囲まれたリスト内の初期化子が少ない場合、または配列内の要素よりも既知のサイズの配列を初期化するために使用される文字列リテラル内の文字が少ない場合、集合体の残りの部分は静的ストレージ期間を持つオブジェクトと同じように暗黙的に初期化されます。

gccsは、指定されたイニシャライザで警告しない-Wmissing-field-initializersように文書化されています。さらに警告を発する機能強化のリクエストがあります: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39589-Wmissing-field-initializers=2

したがって、そのバグ レポートに希望を追加するか、パッチを提供することをお勧めします。オープンソース ソフトウェアに関する私の経験からすると、パッチを追加するのが最善です。

于 2013-10-17T16:24:22.840 に答える