1

x86_64 Linux ボックスで GCC 4.5.3 を使用して構造体を初期化すると、非常に奇妙な問題が発生します。

問題のコード:

struct apr_finfo_t info = { 0 };

apr_finfo_t はかなり複雑な構造体です。私はそれが17の複雑な他のメンバーを持っていると言います.

struct apr_finfo_t {
    /** Allocates memory and closes lingering handles in the specified pool */
    apr_pool_t *pool;
    /** The bitmask describing valid fields of this apr_finfo_t structure 
     *  including all available 'wanted' fields and potentially more */
    apr_int32_t valid;
    /** The access permissions of the file.  Mimics Unix access rights. */
    apr_fileperms_t protection;
    /** The type of file.  One of APR_REG, APR_DIR, APR_CHR, APR_BLK, APR_PIPE, 
     * APR_LNK or APR_SOCK.  If the type is undetermined, the value is APR_NOFILE.
     * If the type cannot be determined, the value is APR_UNKFILE.
     */
    apr_filetype_e filetype;
    /** The user id that owns the file */
    apr_uid_t user;
    /** The group id that owns the file */
    apr_gid_t group;
    /** The inode of the file. */
    apr_ino_t inode;
    /** The id of the device the file is on. */
    apr_dev_t device;
    /** The number of hard links to the file. */
    apr_int32_t nlink;
    /** The size of the file */
    apr_off_t size;
    /** The storage size consumed by the file */
    apr_off_t csize;
    /** The time the file was last accessed */
    apr_time_t atime;
    /** The time the file was last modified */
    apr_time_t mtime;
    /** The time the file was created, or the inode was last changed */
    apr_time_t ctime;
    /** The pathname of the file (possibly unrooted) */
    const char *fname;
    /** The file's name (no path) in filesystem case */
    const char *name;
    /** The file's handle, if accessed (can be submitted to apr_duphandle) */
    struct apr_file_t *filehand;
};

この部分を GCC 4.5.3 および-std=c99 -pedantic -Wextraでコンパイルすると、次の警告メッセージが表示されます。

src/switch_apr.c: In function ‘switch_file_exists’:
src/switch_apr.c:518: warning: missing initializer
src/switch_apr.c:518: warning: (near initialization for ‘info.valid’)

明らかに、GCC は最初のメンバーを初期化しようとしますが、すでに 2 番目のメンバーをチョークしています。-W / -Wextraでビルドしない場合、この警告は発生しません。

各メンバーを手動で初期化することもできましたが、それは奇妙で間違っているように思えます。

Google 検索から収集できたものから、この初期化は完全に合法であり、GCC 3 が機能するというレポートがあるようです。ただし、GCC 4.5 または 4.1 ではありません。

誰かが助けてくれることを願っています。:)

よろしくお願いします、

ミハイ

4

2 に答える 2

3

-Wextraコマンドライン オプションには、-Wmissing-field-initializers. コマンドラインに
追加してみてください。-Wno-missing-field-initializers

$ 猫 7724939.c
#include <stdlib.h>

なんでも構造化 {
  int a;
  int j;
  int k;
};

int main(void) {
  なんでも構造化 x = {0};
  if (xk) return EXIT_FAILURE;
  0 を返します。
}
$ gcc --バージョン
gcc (デビアン 4.6.1-4) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
これはフリー ソフトウェアです。条件のコピーについてはソースを参照してください。いいえ
保証; 商品性や特定の目的への適合性のためでさえありません。

$ gcc -std=c99 -pedantic 7724939.c
$ gcc -std=c99 -pedantic -Wall -Wextra 7724939.c
7724939.c: 関数「main」内:
7724939.c:10:10: 警告: 初期化子がありません [-Wmissing-field-initializers]
7724939.c:10:10: 警告: ('x.j' の初期化に近い) [-Wmissing-field-initializers]
$ gcc -std=c99 -pedantic -Wall -Wextra -Wno-missing-field-initializers 7724939.c
$

C 標準では警告は必要ないことに注意してください。それはあなたのコンパイラが(あまりにも)役に立とうとしているだけです。

于 2011-10-11T11:30:34.527 に答える
0

C++ を使用している場合は、初期化するコンストラクターを含める方がはるかに優れています。そうすれば、初期化はどこでもではなく、コンストラクターに記述するだけで済みます。

于 2011-10-11T11:46:52.460 に答える