C GTK&x2B;3.0警告:字段‘缺少初始值设定项;填充&x2019;属于‘;间隙输入’;

C GTK&x2B;3.0警告:字段‘缺少初始值设定项;填充&x2019;属于‘;间隙输入’;,c,C,我是从gnome gtk+网站上了解这一点的,我是gtk+新手,在c语言中并没有那么高级。我对这段代码有一些问题: static GActionEntry app_entries[] = { {"preferences", preferences_activated, NULL, NULL, NULL}, {"quit", quit_activated, NULL, NULL, NULL} }; 当我用-We

我是从gnome gtk+网站上了解这一点的,我是gtk+新手,在c语言中并没有那么高级。我对这段代码有一些问题:

   static GActionEntry app_entries[] = {
        {"preferences", preferences_activated, NULL, NULL, NULL},
        {"quit", quit_activated, NULL, NULL, NULL}
    };
当我用
-Wextra-Wall-g-O2-pedantic errors
编译它时,它抛出缺少初始值设定项的警告:

gcc -c -o app.o -Wextra -Wall -O2 -pedantic-errors -g `pkg-config --cflags gtk+-3.0` app.c
app.c:38:2: warning: missing initializer for field ‘padding’ of ‘GActionEntry’ [-Wmissing-field-initializers]
  { "preferences", preferences_activated, NULL, NULL, NULL },
  ^
In file included from /usr/include/glib-2.0/gio/gio.h:31:0,
                 from /usr/include/gtk-3.0/gdk/gdkapplaunchcontext.h:28,
                 from /usr/include/gtk-3.0/gdk/gdk.h:32,
                 from /usr/include/gtk-3.0/gtk/gtk.h:30,
                 from app.c:1:
/usr/include/glib-2.0/gio/gactionmap.h:72:9: note: ‘padding’ declared here
   gsize padding[3];
         ^
app.c:39:2: warning: missing initializer for field ‘padding’ of ‘GActionEntry’ [-Wmissing-field-initializers]
  { "quit", quit_activated, NULL, NULL, NULL }
  ^
In file included from /usr/include/glib-2.0/gio/gio.h:31:0,
                 from /usr/include/gtk-3.0/gdk/gdkapplaunchcontext.h:28,
                 from /usr/include/gtk-3.0/gdk/gdk.h:32,
                 from /usr/include/gtk-3.0/gtk/gtk.h:30,
                 from app.c:1:
/usr/include/glib-2.0/gio/gactionmap.h:72:9: note: ‘padding’ declared here
   gsize padding[3];
         ^
为什么我会收到这个警告?我怎样才能修好它


提前感谢查看头文件/usr/include/glib-2.0/gio/gactionmap.h,我们发现
GActionEntry
定义如下:

struct _GActionEntry
{
    const gchar *name;
    void (*activate) (GSimpleAction *action, GVariant *parameter, gpointer user_data);
    const gchar *parameter_type;
    const gchar *state;
    void (* change_state) (GSimpleAction *action, GVariant *value, gpointer user_data);
    /*< private >*/
    gsize padding[3];
};

typedef struct _GActionEntry GActionEntry;
正如在他的文章中所指出的,这是因为GActionEntry有一个私有的“padding”字段,它在代码中没有初始化。GCC警告您这一点

但是,您可以通过使用指定的初始值设定项来欺骗GCC。看一看

-Wmissing字段初始值设定项

此选项不会警告指定的初始值设定项,因此以下修改不会触发警告:

     struct s { int f, g, h; };
     struct s x = { .f = 3, .g = 4 };
如果只想初始化结构的几个字段,则指定的初始值设定项很有用。根据C99标准,未初始化字段将设置为零

(C99第6.7.8.19节)如果大括号内的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文本中的字符少于数组中的元素,则聚合的其余部分应隐式初始化,与具有静态存储持续时间的对象相同。"

通过使用指定的初始值设定项,您的代码可以如下所示:

static GActionEntry app_entries[] = {
    { .name = "preferences", .activate = preferences_activated },
    { .name = "quit",        .activate = quit_activated }
};
这样的代码不会引起GCC的警告

当然,GCC无法区分故意省略的字段和真正忘记初始化的字段。通过使用此语法,您将不会收到更多警告,这是您自己的事情

另外,请注意,C99之前的C中不存在指定的初始值设定项。

请与GActionMap一起查看(紧靠
GActionEntry
static GActionEntry app_entries[] = {
    { .name = "preferences", .activate = preferences_activated },
    { .name = "quit",        .activate = quit_activated }
};