gcc4.9,禁用包含文件跟踪,来自警告

时间:2015-04-10 18:37:26

标签: c gcc4.9

我刚搬到gcc4.9。现在当我运行make来编译我的程序时,我注意到消息的冗长程度大大增加了。特别是在警告中,我收到了更多我不需要的信息,主要是这样的信息:

myfile.c: In function 'myfunc':
myfile.c:4677:10: warning: passing argument 1 of 'sprintf' from incompatible pointer type
sprintf(str1,"file.txt");
          ^
In file included from /usr/include/features.h:374:0,
                 from /usr/include/stdio.h:27,
                 from myfile.c:28:
/usr/include/i386-linux-gnu/bits/stdio2.h:31:1: note: expected 'char * __restrict__' but argument is of type 'char **'
 __NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...))
 ^

我的编译参数始终与“-g -O3”相同。 我尝试了-g0和-g1,但冗长度并没有降低 所以想问一下,如何设置gcc来抑制警告中所有那些过多的编译时消息,一切都从“在文件中包含...”开始,之后是什么? 的 编辑:
我想我必须详细说明我想要实现的目标 我想要警告,所以我不需要-w选项 我想看看:

myfile.c: In function 'myfunc':
myfile.c:4677:10: warning: passing argument 1 of 'sprintf' from incompatible pointer type
sprintf(str1,"file.txt");
          ^

希望看到:

In file included from /usr/include/features.h:374:0,
                 from /usr/include/stdio.h:27,
                 from myfile.c:28:
/usr/include/i386-linux-gnu/bits/stdio2.h:31:1: note: expected 'char * __restrict__' but argument is of type 'char **'
 __NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...))

我不感兴趣原始sprintf在a中声明,由b调用(...实际上可能对此感兴趣......?!?)
以前的gcc版本没有这个问题,所以我最好的猜测,gcc4.9中必须有一些新的选项来删除它(但是我找不到它)
有没有人知道如何从“在文件中包含...”中删除所有内容(在警告中)? 感谢

2 个答案:

答案 0 :(得分:3)

强烈建议您不要这样做,但如果您坚持: gcc -w禁止所有警告。这是你可以通过谷歌搜索&gcc抑制警告发现的东西。 。 。

那就是说,警告是有效的 - 你似乎在你的代码中做了错误的事情。如果你想摆脱警告,为什么不修复代码?然后你有更好的代码没有警告。

答案 1 :(得分:2)

  

您的建议是解决方法,但我仍然可以尝试。你能否在这里写一下你谈到的过滤器?

行;我创建了一个shell脚本来完成这项艰苦的工作。有两种方法可以处理它。一种是调用脚本gcc-filter,然后调用而不是运行:

gcc -g -O3 -Wall -Wextra -Werror -I/where/ever -c source.c

你会跑:

gcc-filter gcc -g -O3 -Wall -Wextra -Werror -I/where/ever -c source.c

使用make,您可以通过指定CC="gcc-filter gcc"或等效项来实现。

另一种方法是在重定向输出后运行脚本:

gcc -g -O3 -Wall -Wextra -Werror -I/where/ever -c source.c 2>&1 | gcc-filter

我将假设第一种技术。

gcc-filter.sh

"$@" 2>&1 |
sed '/^In file /,/^ *^/d' >&2

第一行使用命令行中指定的参数运行gcc(或由参数指定的任何命令;它不必是gcc)。它将标准输出和标准错误重定向到管道(我将回到此处),这将转到sed

sed行在行的开头查找模式In file,并从那里删除直到在可选空格后以插入符号开头的第一行。重定向将它传递的信息发送到标准错误。

脚本有两个主要缺陷:

  1. 它假定标准输出和标准错误可以合并(或者更简洁,gcc对标准输出的写入不多。)
  2. 它解决了一种错误报告模式。如果还有其他应该过滤的序列,则需要添加到sed脚本。
  3. 你可以处理标准输出与标准错误问题,但它有点令人兴奋(也许是“精神膨胀”)。

    (
    "$@" 2>&1 1>&3 |
    sed '/^In file /,/^ *^/d' >&2
    ) 3>&1
    

    子shell ( ... ) 3>&1将写入文件描述符3的数据发送到标准输出。

    子shell 2>&1 1>&3 |内部安排:

    1. 转到管道的标准输出。
    2. 标准输出的标准错误(管道)。
    3. 转到文件描述符3的标准输出(不改变标准错误的位置,管道)。
    4. sed命令因此从gcc获取标准错误输出作为其标准输入,对其进行过滤,>&2将其标准输出发送到标准错误。

      最终结果是标准错误被过滤而标准输出则没有。但是,请注意,由于缓冲的进行,您最终可能会对两个流的输出进行不同的交错。

      另一个问题:退出状态。写入的脚本的退出状态是sed命令的退出状态,在大多数情况下该命令为0。如果我们需要从gcc转发退出状态,我认为我们必须使用Bash set -o pipefail。或者你可以戳PIPESTATUS数组; exit ${PIPESTATUS[0]}应退出时使用gcc退出的相同退出状态。

      演示在Linux上运行的代码

      系统正在运行带有GCC 4.9.2的Ubuntu 14.04 LTS衍生产品。

      测试代码b.c

      (我在其他程序上用尽了x.cy.cz.ca.c。)

      #include <stdio.h>
      
      int main(void)
      {
        char array[512];
        char *buffer = array;
      
        sprintf(&buffer, "file.txt");
        printf("%s\n", buffer);
        return 0;
      }
      

      没有gcc-filter.sh的编译:

      $ make b.o WFLAG3= WFLAG4= WFLAG5= WFLAG6= IFLAGS= LDFLAGS= LDLIBS= cc  -g  -O3 -std=c11 -Wall -Wextra     -Werror    -c -o b.o b.c
      b.c: In function ‘main’:
      b.c:8:3: error: passing argument 1 of ‘sprintf’ from incompatible pointer type [-Werror]
         sprintf(&buffer, "file.txt");
         ^
      In file included from /usr/include/features.h:374:0,
                       from /usr/include/stdio.h:27,
                       from b.c:1:
      /usr/include/x86_64-linux-gnu/bits/stdio2.h:31:1: note: expected ‘char * restrict’ but argument is of type ‘char **’
       __NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...))
       ^
      cc1: all warnings being treated as errors
      <builtin>: recipe for target 'b.o' failed
      make: *** [b.o] Error 1
      $
      

      使用gcc-filter.sh

      进行编译
      $ make b.o CC="./gcc-filter.sh gcc" 
      ./gcc-filter.sh gcc -g -O3 -std=c11 -Wall -Wextra -Werror -c -o b.o b.c
      b.c: In function ‘main’:
      b.c:8:11: error: passing argument 1 of ‘sprintf’ from incompatible pointer type [-Werror]
         sprintf(&buffer, "file.txt");
                 ^
      cc1: all warnings being treated as errors
      <builtin>: recipe for target 'b.o' failed
      make: *** [b.o] Error 1
      $
      

      gcc-filter.sh

      #!/bin/bash
      
      set -o pipefail
      (
      "$@" 2>&1 1>&3 |
      sed '/^In file /,/^ *^/d' >&2
      ) 3>&1
      
      exit ${PIPESTATUS[0]}
      

      另一个测试

      我还创建了c.c,其中包含三条sprintf()行和三条printf()行,过滤后的输出为:

      $ ./gcc-filter.sh gcc -g -O3 -std=c11 -Wall -Wextra -Werror -c c.c
      c.c: In function ‘main’:
      c.c:8:11: error: passing argument 1 of ‘sprintf’ from incompatible pointer type [-Werror]
         sprintf(&buffer, "file1.txt");
                 ^
      c.c:10:11: error: passing argument 1 of ‘sprintf’ from incompatible pointer type [-Werror]
         sprintf(&buffer, "file2.txt");
                 ^
      c.c:12:11: error: passing argument 1 of ‘sprintf’ from incompatible pointer type [-Werror]
         sprintf(&buffer, "file3.txt");
                 ^
      cc1: all warnings being treated as errors
      $
      

      因此可以正确处理多个错误(但是在过去的时间里,多个类似的脚本似乎在错误消息的单个实例上工作,但是在对多个错误消息进行测试时,它对放弃输出过于热心)。 / p>