来自GCC但不是Clang的复合文字和指定的初始化器警告

时间:2018-03-03 06:53:12

标签: c gcc clang designated-initializer compound-literals

使用gcc -std=c99 -Wextra这段代码进行编译:

#include <stdio.h>

struct T {
    int a;
    int *b;
    int c;
};

int main(void)
{
    struct T t = {.b = ((int []){1, 1})};

    printf("%d\n", t.b[1]);
    return 0;
}

给我一​​个警告:

demo.c:11:12: warning: missing initializer for field ‘c’ of ‘struct T’ [-Wmissing-field-initializers]
     struct T t = {.b = ((int []){1, 1})};
            ^
demo.c:6:9: note: ‘c’ declared here
     int c;
         ^

但是指定的初始值设定项应该初始化为其余成员的零,即使它们被省略。

为什么要警告? (clang在没有警告的情况下编译同一段代码)

gcc version 6.3.0 20170516 (Debian 6.3.0-18) 
clang version 3.8.1-24 (tags/RELEASE_381/final)

2 个答案:

答案 0 :(得分:2)

它看起来像是gcc的“一致性错误”,这是gcc/c/c-typeck.c中的相关代码段

 7436   /* Warn when some struct elements are implicitly initialized to zero.  */
 7437   if (warn_missing_field_initializers
 7438       && constructor_type
 7439       && TREE_CODE (constructor_type) == RECORD_TYPE
 7440       && constructor_unfilled_fields)
 7441     {
 7442         bool constructor_zeroinit =
 7443          (vec_safe_length (constructor_elements) == 1
 7444           && integer_zerop ((*constructor_elements)[0].value));
 7445
 7446         /* Do not warn for flexible array members or zero-length arrays.  */
 7447         while (constructor_unfilled_fields
 7448                && (!DECL_SIZE (constructor_unfilled_fields)
 7449                    || integer_zerop (DECL_SIZE (constructor_unfilled_fields))))
 7450           constructor_unfilled_fields = DECL_CHAIN (constructor_unfilled_fields);
 7451
 7452         if (constructor_unfilled_fields
 7453             /* Do not warn if this level of the initializer uses member
 7454                designators; it is likely to be deliberate.  */
 7455             && !constructor_designated
 7456             /* Do not warn about initializing with ` = {0}'.  */
 7457             && !constructor_zeroinit)
 7458           {
 7459             if (warning_at (input_location, OPT_Wmissing_field_initializers,
 7460                             "missing initializer for field %qD of %qT",
 7461                             constructor_unfilled_fields,
 7462                             constructor_type))
 7463               inform (DECL_SOURCE_LOCATION (constructor_unfilled_fields),
 7464                       "%qD declared here", constructor_unfilled_fields);
 7465           }
 7466     }

如果任何属性构造函数具有未填写的字段,该代码的意图似乎是要发出警告。您没有在元素'a'上得到警告的事实很可能是此处的“一致性错误”。

如果-Wextra用于打开缺少的初始化器警告,则它具有。问题是,“缺少初始值设定项警告”是否应排除省略的属性?看来gcc和clang对此意见不一-他们可能会同意吗?

这可能不是您要寻找的答案。但是希望它对您了解情况有所帮助。 :)。 GCC团队有一个一致性错误,但是在这种情况下,他们的代码意图似乎有所警告,而凭经验,c语则不会。

答案 1 :(得分:0)

为什么要警告?

因为-Wmissing-field-initializers-Wextra设置,而您在gcc调用中设置了后者。

-Wextra挑剔,甚至-Wmissing-field-initializers都不是-Wall的元素。

仅省略一些字段初始化器,而不是全部都是错误源。在具有数百个元素的数组/结构中,而您只是对其中的一些进行初始化,那么对于人类来说,仅通过查看代码来掌握它几乎是不可能的。