首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gcc4.9,从警告中禁用包含文件跟踪

gcc4.9,从警告中禁用包含文件跟踪
EN

Stack Overflow用户
提问于 2015-04-10 18:37:25
回答 2查看 219关注 0票数 0

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

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

我确实想看到:

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

我做了,而不是想看到:

代码语言:javascript
复制
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调用(...who实际上可能对此感兴趣.??)

之前的gcc版本没有这个问题,所以我最好的猜测是,在gcc4.9中一定有一些新的选项来删除它(但我找不到)

有谁知道如何删除从“文件包括.”开始的所有内容吗?进一步(在警告中)?

谢谢

EN

回答 2

Stack Overflow用户

发布于 2015-04-10 19:22:21

我强烈建议您不要这样做,但如果您坚持:禁止所有警告。这是你可以在谷歌上搜索“gcc压制警告”时发现的。。。

尽管如此,警告是有效的--您似乎在代码中做了错误的事情。如果您想消除警告,为什么不修复代码呢?那么您有更好的代码和没有警告。

票数 3
EN

Stack Overflow用户

发布于 2015-04-10 21:55:43

你的建议是一个解决办法,但我还是可以试试。你能把你说的那个过滤器写在这里吗?

好的,我会创建一个shell脚本来做艰苦的工作。处理这个问题有两种方法。一种方法是调用脚本gcc-filter,然后不再运行:

代码语言:javascript
复制
gcc -g -O3 -Wall -Wextra -Werror -I/where/ever -c source.c

你会跑:

代码语言:javascript
复制
gcc-filter gcc -g -O3 -Wall -Wextra -Werror -I/where/ever -c source.c

使用make,您可以通过指定CC="gcc-filter gcc"或等效的方法来实现这一点。

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

代码语言:javascript
复制
gcc -g -O3 -Wall -Wextra -Werror -I/where/ever -c source.c 2>&1 | gcc-filter

我将假设第一种技术。

gcc-filter.sh

代码语言:javascript
复制
"$@" 2>&1 |
sed '/^In file /,/^ *^/d' >&2

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

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

该脚本目前有两个主要缺陷:

  1. 它假设可以合并标准输出和标准错误(或者,更简单地说,gcc不会对标准输出写入太多内容)。
  2. 它消除了一种错误报告模式。如果需要过滤其他序列,则需要添加到sed脚本中。

您可以处理标准输出与标准错误问题,但这是轻微的脑震荡(可能是“心灵膨胀”)。

代码语言:javascript
复制
(
"$@" 2>&1 1>&3 |
sed '/^In file /,/^ *^/d' >&2
) 3>&1

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

在子shell 2>&1 1>&3 |中安排:

  1. 标准输出到管道。
  2. 标准错误去标准输出的地方(管道)。
  3. 将标准输出转到文件描述符3(不更改标准错误发生的位置,管道)。

因此,sed命令从gcc获取标准错误输出作为标准输入,过滤它,>&2将其标准输出发送给标准错误。

净结果是,标准错误被过滤,而标准输出不被过滤。但是,请注意,由于缓冲的结果,您可能会从这两个流中得到不同的输出交织。

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

演示在Linux上工作的代码

该系统运行Ubuntu 14.04 LTS导数与GCC 4.9.2。

测试代码b.c

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

代码语言:javascript
复制
#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的编译

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

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

代码语言:javascript
复制
#!/bin/bash

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

exit ${PIPESTATUS[0]}

还有另一个测试

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

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

因此,多个错误是正确处理的(但在过去,不止一个类似的脚本似乎在一个错误消息的单个实例上工作,但是当在多个错误消息上进行测试时,它太热衷于丢弃输出)。

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

https://stackoverflow.com/questions/29568494

复制
相关文章

相似问题

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