Question

I'm looking for an explanation why gcc are giving this warning for me.

I'm compiling with the gcc-3 on cygwin with the -Wunreachable-code flag, and the gcc says this warning for me:

main.c:223: warning: will never be executed

That's this line: while(fgets(line, MAX_LINE, stdin) != NULL) {

This code is inside a if(exp) { } block where exp is dynamically set according to command-line-arguments(parsed by getopt() ), look at the code part:

 if(mystruct.hastab) {

the default value is 0. But it's become 1 if -t flag is passed to application, as you can see at following:

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 {
       //...
      }
    }

So, there's a reason for the code be executed. As happens.

Was it helpful?

Solution

Here's another possibility: the problem is with macros. Here's a simple example that demonstrates your error:

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

When I compile this, I get:

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

The error is not particularly enlightening. However, if you run the preprocessor, look what memset expands to:

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

I suspect because of the constant size of s, only one of the branches of the ?: is ever executed, and this is what gcc is complaining about. In your case, it's probably that fgets is a macro. Run gcc -E, find your problem line in the output, and see if it's wonky (mine isn't, but I'm not running cygwin).

Moral of the story: preprocessors & macros suck.

OTHER TIPS

Sounds like gcc is convinced hastab is never set, or that it is only set after the code it's warning about. It certainly seems like gcc is wrong, but since you only gave us snippets it is hard to be sure. I don't think anyone can help you further unless we see a complete program we can compile ourselves.

If I had to guess I'd say gcc is considering that there are 2 cases where you can call proc() without having set mystruct.hastab to something other than 0.

The first case is if this evaulates to false on the first run through, since you will drop out of the loop without executing your switch statement:

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

The second case is if opt is never 't':

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

So you will fall out of the loop without ever having set mystruct.hastab to a non-zero value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top