GCC 4 结构初始化失败

发布于 2024-12-09 18:05:13 字数 2402 浏览 5 评论 0原文

我在 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 尝试初始化第一个成员,但已经在第二个。 当不使用 -W / -Wextra 构建时,不会出现此警告。

可以手动初始化每个成员,但这听起来很奇怪而且错误。

从我从 Google 搜索中收集到的信息来看,这种初始化似乎是完全合法的,并且有关于 GCC 3 的报告,它可以在其中工作。但 GCC 4.5 或 4.1 则不然。

希望有人能帮忙。 :)

最好的问候,

米哈伊

I have a very weird issue whilst initializing a struct with GCC 4.5.3 on my x86_64 Linux box.

Code in question:

struct apr_finfo_t info = { 0 };

apr_finfo_t is quite some complex struct. I'll just say it has 17 complex other members.

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;
};

Now, when compiling this piece with GCC 4.5.3 and -std=c99 -pedantic -Wextra, I'm seeing following warning message:

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’)

Obviously GCC tries to initialize the first member, but already chokes on the second one.
This warning does NOT occur when not building with -W / -Wextra.

I could initialize each member by hand but that sounds weird and wrong.

From what I could gather from a Google search, it seems this initialization is perfectly legit and there are reports for GCC 3 where it works. Not with GCC 4.5 or 4.1 though.

Hope someone can help. :)

Best regards,

Mihai

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

提笔落墨 2024-12-16 18:05:14

如果您使用 C++,最好包含一个初始化的构造函数,这样初始化只需要写在构造函数中,而不是到处写。

If you are using C++ it would be much better to include a constructor that initialises, that way initialisation would only need to be written in the constructor instead of everywhere.

知足的幸福 2024-12-16 18:05:13

-Wextra 命令行选项包括 -Wmissing-field-initializers
尝试将 -Wno-missing-field-initializers 添加到命令行中。

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

struct whatever {
  int a;
  int j;
  int k;
};

int main(void) {
  struct whatever x = {0};
  if (x.k) return EXIT_FAILURE;
  return 0;
}
$ gcc --version
gcc (Debian 4.6.1-4) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gcc -std=c99 -pedantic 7724939.c 
$ gcc -std=c99 -pedantic -Wall -Wextra 7724939.c 
7724939.c: In function ‘main’:
7724939.c:10:10: warning: missing initializer [-Wmissing-field-initializers]
7724939.c:10:10: warning: (near initialization for ‘x.j’) [-Wmissing-field-initializers]
$ gcc -std=c99 -pedantic -Wall -Wextra -Wno-missing-field-initializers 7724939.c 
$ 

请注意,C 标准不要求使用警告。这只是你的编译器试图提供(太)帮助。

The -Wextra command-line option includes the -Wmissing-field-initializers.
Try adding -Wno-missing-field-initializers to your command-line.

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

struct whatever {
  int a;
  int j;
  int k;
};

int main(void) {
  struct whatever x = {0};
  if (x.k) return EXIT_FAILURE;
  return 0;
}
$ gcc --version
gcc (Debian 4.6.1-4) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gcc -std=c99 -pedantic 7724939.c 
$ gcc -std=c99 -pedantic -Wall -Wextra 7724939.c 
7724939.c: In function ‘main’:
7724939.c:10:10: warning: missing initializer [-Wmissing-field-initializers]
7724939.c:10:10: warning: (near initialization for ‘x.j’) [-Wmissing-field-initializers]
$ gcc -std=c99 -pedantic -Wall -Wextra -Wno-missing-field-initializers 7724939.c 
$ 

Note that the warning is not required by the C Standard. It's just your compiler trying to be (too) helpful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文