在GCC中,如果我初始化结构但缺少元素,是否有任何标志警告我?

在GCC中,如果我初始化结构但缺少元素,是否有任何标志警告我?,gcc,c,struct,warnings,compiler-warnings,Gcc,C,Struct,Warnings,Compiler Warnings,假设我有这个结构 typedef struct foo { int a; char b; char *c; } foo; 我想创建结构的一个初始化实例 foo bar = { .a = 7 .b = 'x' .c = "hello" }; 但是,如果我搞砸了,忘记初始化我正在初始化的结构中的一个元素怎么办。。。例如 foo bar = { .a = 7, .c = "hello" }; 。。。我只是忘了初始化元素“b”——在我给出的示例中,这是一个很容易检测到的错误,但对于更复

假设我有这个结构

typedef struct foo {
  int a;
  char b;
  char *c;
} foo;
我想创建结构的一个初始化实例

foo bar = { .a = 7 .b = 'x' .c = "hello" };
但是,如果我搞砸了,忘记初始化我正在初始化的结构中的一个元素怎么办。。。例如

foo bar = { .a = 7, .c = "hello" };
。。。我只是忘了初始化元素“b”——在我给出的示例中,这是一个很容易检测到的错误,但对于更复杂的结构,尤其是在开发中的结构,这显然是合理的

如果我做了这样的错误,有没有任何标志可以传递给它,导致它生成警告

  • 您必须将“-W”选项传递给gcc
  • 代码中的用户栏.a代替.a
  • 如果使用“gcc-wtest.c”命令编译代码,则可以看到以下警告消息

    使用“老派”ISO C初始化结构的方式(当不使用
    -std=c99
    编译时),默认情况下,gcc应该给您一个警告。除此之外,您需要设置的gcc标志是
    -Wmissing字段初始值设定项
    ,它在默认情况下是启用的,但在默认情况下不是启用的,而是
    -Wextra
    的一部分,如Michael Burr在其评论中所述,只要您使用以下语法:

    int main ( void )
    {
        foo bar = {123, "foobar"};//failed to init char b member
        foo zar = {123, '\a'};//omitted c initialization 
        return 0;
    }
    
    这将发出以下警告:

    warning: initialization makes integer from pointer without a cast [enabled by default] foo bar = { 123, "foobar"}; warning: missing initializer for field ‘c’ of ‘foo’ [-Wmissing-field-initializers] foo zar = { 123, 'a'}; 那是最安全的方法。。。按如下方式调用此函数:

    foo *new_foo = init_foo( NULL, 123, '\a', "string");//allocate new struct, set all members
    //free like so:
    free_foo(&new_foo);//pass pointer to pointer
    foo stack_foo;
    init_foo(&stack_foo, 123, '\a', "string");//initialize given struct
    //only free .c member
    free(stack_foo.c);
    stack_foo.c = NULL;
    

    无论如何,在开发过程中,总是使用
    -Wall
    进行编译,为了安全起见,也要使用
    -pedantic

    {.a=7.b='x'.c=“hello”}
    需要
    哦,是的——thanx BLUEPIXY--我通常都记得,我只是忘记了当我出于某种原因键入问题时——但是谢谢……GCC有
    -Wmissing字段初始值设定项
    (包含在
    -Wextra
    中),但无论出于何种原因,在使用指定的初始值设定项时都不适用它,只有在使用“位置”初始值设定项时才使用。@MichaelBurr:希望你不介意我在回答中引用这句话,但我相信你:)你能举一段源代码作为例子吗?我试过你的建议,很明显我遗漏了一些东西。当我用bar.a替换.a时,它给了我一个语法错误。C编译器不允许这样做。无论我使用.a还是bar.a,我都没有发现由-W选项引起的任何行为差异。不管有没有它,如果我只放了.a,编译器都不会抱怨——不管有没有它,如果我放了bar.a,我都会得到同样的错误消息。但是,如果我遗漏了什么,一个实际的代码示例可能会澄清这一点。旧的
    -W
    开关和更具体的
    -Wmissing字段初始值设定项不能与指定的初始值设定项一起工作。
    foo bar={bar.a=7,bar.c=“hello”}
    不能满足您的要求<代码>条形图。a=7
    不是指定的初始值设定项。这是一项任务。对该作业进行评估,结果为7。然后该值用于初始化第一个字段
    a
    。类似地,
    bar.c=“hello”
    计算字符串的地址,并用于初始化第二个字段,
    b
    @MRaja:您给出的示例不是用于初始化结构的正确c语法。如果您在全局空间中初始化结构时尝试这样做,编译器将自己通知您——不是通过警告,而是通过错误。如果在函数内部执行此操作,则可以不受影响,因为C具有相同的功能,可以通过键入
    C=(b=a)将
    a
    的值复制到
    b
    C
    ---但是,在初始化结构时,在结构括号中命名元素
    a
    时,bar.a不是正确的语法。@user308003:只是在代码本身的帮助下尝试使用-W选项获得警告。我不担心其他事情,除了为我正在寻找的东西生成警告,因为我们不是初学者:),如果我的答案是错误的,那么请忽略它。谢谢。谢谢,埃利亚斯。:-)您给出的语法很有用。:-)在后面的例子中,你给出了
    foobar={123,'a'}
    ——如果我将
    -W
    选项传递给
    gcc
    ,它甚至会给我一个警告。当然,我从其他回答的人那里得到了<代码> -W/COD>选项,但是我认为你的答案更好,因为另一个人在他的回答中也提出了其他建议,即使我没有忘记任何元素,编译器也会完全陷入困境。所以我选择你的答案作为“被接受的答案”。无论谁投了反对票:请,我不介意,但我想知道为什么,也许链接到一些我应该阅读的文档on@user3080003:干杯,请注意,我尝试了更多的方法,找到了更可靠的方法,以及触发警告的特定GCC标志。也可以考虑使用自定义函数,如果可以的话,因为它确实允许你分配<代码> char *<代码>成员,如果你想要的话……我也奇怪为什么有人否决了你的答案,埃利亚斯。我认为你对这个问题给出了最好的答案。好吧——现在我甚至有一个问题,就是“学究式”选项没有给出我需要的错误。
    foo * init_foo(foo *str, int a, char b, char *c)
    {
        if (c == NULL) return NULL;// no char pointer passed
        if (str == NULL) str = malloc(sizeof *str);//function allocates struct, too
        str->a = a;
        str->b = b;
        str->c = calloc(strlen(c) + 1, sizeof *(str->c));//allocate char pointer
        strcpy(str->c, c);
        return str;
    }
    //optionally include custom free function:
    void free_foo ( foo **f)
    {
        if ((*f)->c != NULL) free((*f)->c);
        free(*f)
        *f = NULL;//init pointer to NULL
    }
    
    foo *new_foo = init_foo( NULL, 123, '\a', "string");//allocate new struct, set all members
    //free like so:
    free_foo(&new_foo);//pass pointer to pointer
    foo stack_foo;
    init_foo(&stack_foo, 123, '\a', "string");//initialize given struct
    //only free .c member
    free(stack_foo.c);
    stack_foo.c = NULL;