0

gccなぜこの警告が表示されるのか、説明を探しています。

gcc-3フラグを付けてoncygwinでコンパイルしてい-Wunreachable-codeますが、gcc は次の警告を表示します。

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のブランチの1つだけ?:が実行されているのではないかと思います。これは、gccが不満を言っていることです。あなたの場合、それfgetsはおそらくマクロです。を実行gcc -Eし、出力で問題の行を見つけて、それが不安定かどうかを確認します(私のものはそうではありませんが、私はcygwinを実行していません)。

話の教訓:プリプロセッサとマクロは最悪だ。

于 2012-07-20T21:57:40.780 に答える
1

推測する必要がある場合は、 gcc以外にproc()設定せずに呼び出すことができる2つのケースがあると考えていると思います.mystruct.hastab0

最初のケースは、ステートメントfalseを実行せずにループから抜け出すため、これが最初の実行時に評価される場合です。switch

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

2 番目のケースは if optis never't'です:

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

mystruct.hastabしたがって、ゼロ以外の値に設定することなく、ループから抜け出します。

于 2012-07-20T21:45:23.307 に答える