简体   繁体   English

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

[英]Compound literal and designated initializer warning from GCC but not Clang

Compiling with gcc -std=c99 -Wextra this piece of code: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;
}

Is giving me a warning:是在给我一个警告:

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

But designated initializers are supposed to initialize to zero the rest of the members even if they are ommited.但是指定的初始值设定项应该将其余成员初始化为零,即使它们被省略也是如此。

Why the warning?为什么警告? ( clang compiles the same piece of code without warnings) clang编译同一段代码时没有警告)

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

It looks like a gcc "consistency bug", here is the relevant code snippet in gcc/c/c-typeck.c它看起来像一个 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     }

The intent of the code appears to be to warn if any attribute constructor has an unfilled-field.代码的意图似乎是警告任何属性构造函数是否具有未填充字段。 The fact that you are not getting a warning on element 'a' is likely the "consistency bug" here.您没有在元素“a”上收到警告的事实可能是此处的“一致性错误”。

If -Wextra is intended to turn on the missing initializers warning, then it has.如果-Wextra旨在打开缺少的初始化程序警告,那么它有。 The question is, should the "missing initializers warning" exclude omitted attributes?问题是,“缺少初始化程序警告”是否应该排除省略的属性? It seems that gcc and clang disagree about this - and it might be fine for them to? gcc 和 clang 似乎不同意这一点——他们这样做可能没问题吗?

This may not be the answer you are looking for.. but hope it helps with your understanding of the situation.这可能不是您正在寻找的答案.. 但希望它有助于您了解情况。 :). :). GCC team has a consistency bug, but their code's intent seems to be warn in these cases, whereas clang, empirically, will not. GCC 团队有一个一致性错误,但在这些情况下,他们的代码的意图似乎是警告,而根据经验,clang 不会。

Why the warning?为什么警告?

Because -Wmissing-field-initializers is set by -Wextra and you set the latter in the gcc call.因为-Wmissing-field-initializers是由-Wextra设置的,而您在gcc调用中设置了后者。

-Wextra is picky, and -Wmissing-field-initializers is not even element of -Wall . -Wextra很挑剔,而-Wmissing-field-initializers甚至不是-Wall的元素。

Omitting just some field initializers but not all is a source of error.只省略一些字段初始值设定项而不是全部是错误的来源。 In an array / struct with has some hundreds elements and you are just initializing some of them, then it's almost impossible for a human to grasp that by just looking at the code.在具有数百个元素的数组/结构中,您只是初始化其中的一些元素,那么人类几乎不可能仅通过查看代码来掌握它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM