GCC,空结构和-Wunused-result

时间:2017-09-07 12:39:00

标签: gcc

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

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();
                      ^~~~~~

clang不会发出警告。

这是一个错误还是一个功能?

(作为返回值的空结构在某些代码生成方案中很有用,其中总是需要返回值,但不在问题

1 个答案:

答案 0 :(得分:1)

这确实是GCC中的一个错误。我向他们提交了a bug report

解决方法是在“空”结构中包含无名域位:

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);
}

仅警告'should_warn'。这确实意味着sizeof(struct Empty)为1而不是0,并且GCC在shouldnt_warn_1shouldnt_warn_2中生成了额外的移动指令,但这些可能是可接受的副作用。

(注意,没有字段的结构和没有名为字段的结构体)都是GNU扩展 - 在ISO C中,每个结构中必须包含至少一个命名字段。然而,位域是标准的,只是模糊不清。)