来自 GCC 但不是 Clang 的复合文字和指定初始化程序警告
Compound literal and designated initializer warning from GCC but not Clang
用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)
Why the warning?
因为 -Wmissing-field-initializers
是由 -Wextra
设置的,而你在 gcc
调用中设置了后者。
-Wextra
很挑剔,-Wmissing-field-initializers
甚至不是 -Wall
.
的元素
仅省略一些字段初始值设定项而不是全部是错误来源。在一个有数百个元素的数组/结构中,你只是初始化其中的一些,那么人类几乎不可能通过查看代码来掌握它。
它看起来像一个 gcc "consistency bug",这里是 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' 上收到警告的事实可能是此处的 "consistency bug"。
如果 -Wextra
旨在打开缺少初始化程序警告,那么它已经打开了。问题是,"missing initializers warning" 是否应该排除省略的属性? gcc 和 clang 似乎不同意这一点——他们这样做可能没问题?
这可能不是您要找的答案..但希望它能帮助您了解情况。 :). GCC 团队有一个一致性错误,但在这些情况下,他们的代码的意图似乎是警告,而根据经验,clang 不会。
用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)
Why the warning?
因为 -Wmissing-field-initializers
是由 -Wextra
设置的,而你在 gcc
调用中设置了后者。
-Wextra
很挑剔,-Wmissing-field-initializers
甚至不是 -Wall
.
仅省略一些字段初始值设定项而不是全部是错误来源。在一个有数百个元素的数组/结构中,你只是初始化其中的一些,那么人类几乎不可能通过查看代码来掌握它。
它看起来像一个 gcc "consistency bug",这里是 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' 上收到警告的事实可能是此处的 "consistency bug"。
如果 -Wextra
旨在打开缺少初始化程序警告,那么它已经打开了。问题是,"missing initializers warning" 是否应该排除省略的属性? gcc 和 clang 似乎不同意这一点——他们这样做可能没问题?
这可能不是您要找的答案..但希望它能帮助您了解情况。 :). GCC 团队有一个一致性错误,但在这些情况下,他们的代码的意图似乎是警告,而根据经验,clang 不会。