0

我正在寻找解释为什么要给我gcc这个警告。

我正在使用带有标志的gcc-3on进行编译,gcc 对我说这个警告:cygwin-Wunreachable-code

main.c:223:警告:永远不会被执行

就是这一行:while(fgets(line, MAX_LINE, stdin) != NULL) {

此代码位于根据命令行参数(由 解析)动态设置的if(exp) { }块内,请查看代码部分:expgetopt()

 if(mystruct.hastab) {

默认值为0. 但是1如果将-t标志传递给应用程序,它就变成了,如下所示:

struct mystruct_t {
   //... 
   int hastab;
} mystruct;

    int main(int argc, char *argv[])
    {

      int opt;
        memset(&mystruct, 0, sizeof(mystruct));
         while((opt = getopt(argc, argv, optString)) != -1) {
            switch(opt) {
              case 't':
               mystruct.hastab = 1;
               break;
              //....
            }
        }
         proc();
        return 0;
    }

    void 
    proc(void)
    {
      char *buf, *tmpbuf, line[MAX_LINE + 1], *p, *fullfilename;

      if(mystruct.hastab) {

        while(fgets(line, MAX_LINE, stdin) != NULL) {
           //...
        }
      } else {
       //...
      }
    }

因此,执行代码是有原因的。碰巧。

4

3 回答 3

3

听起来 gcc 确信hastab永远不会设置,或者它只在它警告的代码之后设置。看起来 gcc 确实是错误的,但是由于您只给了我们片段,因此很难确定。我认为除非我们看到可以自己编译的完整程序,否则没有人可以进一步帮助您。

于 2012-07-20T20:16:16.063 回答
2

这是另一种可能性:问题出在宏上。这是一个演示您的错误的简单示例:

#include <string.h>
int s;
int main(int argc, char *argv[]) {
  memset(&s, 0, sizeof(s));
}

当我编译这个时,我得到:

$ gcc -Wunreachable-code tmp.c
tmp.c: In function ‘main’:
tmp.c:4: warning: will never be executed

这个错误并不是特别有启发性。但是,如果您运行预处理器,请查看memset扩展为:

$ gcc -E tmp.c

...
int s;
int main(int argc, char *argv[]) {
  ((__builtin_object_size (&s, 0) != (size_t) -1) ? __builtin___memset_chk (&s, 0, sizeof(s), __builtin_object_size (&s, 0)) : __inline_memset_chk (&s, 0, sizeof(s)));
}

我怀疑由于 的大小恒定s,只有一个分支?:被执行,这就是 gcc 所抱怨的。在您的情况下,这可能fgets是一个宏。运行gcc -E,在输出中找到你的问题行,看看它是否有问题(我的不是,但我没有运行 cygwin)。

故事的寓意:预处理器和宏很烂。

于 2012-07-20T21:57:40.780 回答
1

如果我不得不猜测,我会说 gcc 正在考虑有 2 种情况,您可以在proc()没有设置mystruct.hastab0.

第一种情况是如果这false在第一次运行时评估为,因为您将退出循环而不执行您的switch语句:

while((opt = getopt(argc, argv, optString)) != -1) {

第二种情况是 if optis never 't'

switch(opt) {
case 't':
    mystruct.hastab = 1;

因此,您将退出循环,而无需设置mystruct.hastab为非零值。

于 2012-07-20T21:45:23.307 回答