GCC、空结构和-Wunused结果

GCC、空结构和-Wunused结果,gcc,Gcc,以下程序导致gcc发出-Wunused结果: struct Empty { }; __attribute__((warn_unused_result)) static struct Empty func(void) { return (struct Empty){}; } int main(void) { struct Empty res = func(); (void)res; return 0; } 编译器输出: gcc -Wall -Wextra /tmp/test.

以下程序导致gcc发出-Wunused结果:

struct Empty { };

__attribute__((warn_unused_result))
static struct Empty func(void) {
  return (struct Empty){};
}

int main(void) {
  struct Empty res = func();
  (void)res;
  return 0;
}
编译器输出:

gcc -Wall -Wextra /tmp/test.c -c -o /tmp/test
/tmp/test.c: In function ‘main’:
/tmp/test.c:12:22: warning: ignoring return value of ‘func’, declared with attribute warn_unused_result [-Wunused-result]
   struct Empty res = func();
                      ^~~~~~
叮当声不会发出警告

这是一个bug还是一个特性


(空struct as return value在某些代码生成场景中非常有用,因为在这些场景中,返回值总是被期望的,但这与问题无关)

这确实是GCC中的一个bug。我向他们提出申请

解决方法是在“空”结构中包含一个无名的位字段:

struct Empty {char:1;};

extern void use_empty(struct Empty);

__attribute__((warn_unused_result))
extern struct Empty make_empty(void);

void should_warn(void)
{
    make_empty();
}

void shouldnt_warn_1(void)
{
    use_empty(make_empty());
}

void shouldnt_warn_2(void)
{
    struct Empty e = make_empty();
    use_empty(e);
}
仅针对“应警告”发出警告。这确实意味着
sizeof(struct Empty)
是1而不是0,GCC在
shouldnt\u warn\u 1
shouldnt\u warn\u 2
中生成一条额外的移动指令,但这些可能是可以接受的副作用


(请注意,一个完全没有字段的结构和一个没有命名字段的结构都是GNU扩展-在ISO C中,每个结构中必须至少包含一个命名字段。但是,无名的位字段是标准的,只是模糊的。)

这在我看来像是一个bug,因为它无助于实际使用
res
。(强制转换为void故意不足以抑制此警告。)我可以用gcc 7()重现问题,因此请在@zwol提交错误报告。不幸的是,用户帐户创建无法正确处理gcc bugzillaOh。我帮你归档了: