首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gcc报告了该行的“永远不会执行”:will(line,MAX_LINE,stdin) != NULL)

gcc报告了该行的“永远不会执行”:will(line,MAX_LINE,stdin) != NULL)
EN

Stack Overflow用户
提问于 2012-07-20 20:11:47
回答 3查看 2.7K关注 0票数 0

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

我正在用gcc-3 on cygwin编写带有-Wunreachable-code标志的代码,gcc为我说了这个警告:

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

这句话是:while(fgets(line, MAX_LINE, stdin) != NULL) {

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

代码语言:javascript
复制
 if(mystruct.hastab) {

默认值是0。但是,如果将1标志传递给应用程序,则会变成-t,如下所示:

代码语言:javascript
复制
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 {
       //...
      }
    }

所以,执行代码是有原因的。恰巧发生了。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-07-20 21:57:40

还有一种可能性:问题在于宏。下面是一个简单的示例,演示了您的错误:

代码语言:javascript
复制
#include <string.h>
int s;
int main(int argc, char *argv[]) {
  memset(&s, 0, sizeof(s));
}

当我编译它时,我得到:

代码语言:javascript
复制
$ gcc -Wunreachable-code tmp.c
tmp.c: In function ‘main’:
tmp.c:4: warning: will never be executed

这一错误并不特别具有启发性。但是,如果运行预处理器,请查看memset扩展到的内容:

代码语言:javascript
复制
$ 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)。

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

票数 2
EN

Stack Overflow用户

发布于 2012-07-20 20:16:16

听起来gcc确信hastab从未被设置过,或者它只是在它警告的代码之后才被设置。当然,gcc似乎错了,但既然你只给了我们一些片段,就很难确定。我认为没有人能进一步帮助你,除非我们看到一个完整的程序,我们可以自己编译。

票数 3
EN

Stack Overflow用户

发布于 2012-07-20 21:45:23

如果我不得不猜的话,我会说gcc在考虑有两种情况下,你可以调用proc(),而不必将mystruct.hastab设置为0以外的东西。

第一种情况是,如果这在第一次运行时会转移到false,因为您将在不执行switch语句的情况下退出循环:

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

第二种情况是,如果opt永远不是't'

代码语言:javascript
复制
switch(opt) {
case 't':
    mystruct.hastab = 1;

因此,在没有将mystruct.hastab设置为非零值的情况下,您将退出循环。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11586339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档