2

我有一段如下形式的代码:

typedef enum {A=1,B} EnumType;

int foo (EnumType x)
{
  int r;
  switch (x) {
    case A:
      r = 1;
      break;
    case B:
      r = 2;
      break;
      /*
    default:
      r = -1;
      break;
      */
  }
  return r;
}

我使用 GCC 6.3.0 编译并收到警告:

$ gcc --version
gcc (MacPorts gcc6 6.3.0_2) 6.3.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gcc -c -Wall -O1 test.c
test.c: In function 'foo':
test.c:20:10: warning: 'r' may be used uninitialized in this function [-Wmaybe-uninitialized]
   return r;
          ^

该代码对我来说似乎是安全的,并且确实有一些关于GCC 会产生误报的讨论。

这是一个虚假的警告吗?

更多相关信息:

  • 添加注释掉的default:块可以解决警告
  • 警告不会出现-O0
4

2 回答 2

5

这个警告是完全正确的,因为一个enum类型不会将可能的值限制在这个定义的成员中enum——它可以保存基础整数类型的任何值。因此,如果default您的开关中没有分支,您确实可以使用r未初始化的代码来显示您的代码。

我可以使用问题中显示的确切代码重现缺少的警告gcc-O0因此在我看来,这就像gcc. 无论优化级别如何,都应发出警告。

于 2017-07-31T07:10:51.720 回答
1

很容易弄清楚:有可能的程序路径 r 将在未初始化的情况下返回。所以你得到了警告。Enum 只是 int 所以你有很多可能的情况。

枚举不会根据值在运行时检查。

关于问题的第二部分。这是有意的,因为任何级别的优化都可能(在这种情况下,如果枚举类型的值是非法的,将删除代码 - 编译器假定没有其他值是可能的)

https://godbolt.org/g/S9XE3d

这个案例最有趣: https ://godbolt.org/g/TDUhN7

您可能认为您检查了非法值。但是编译器已经剥离了代码:)

顺便说一句 - 有趣的是为什么我的回答被否决了

于 2017-07-31T07:12:21.973 回答