我刚搬到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中必须有一些新的选项来删除它(但是我找不到它)
有没有人知道如何从“在文件中包含...”中删除所有内容(在警告中)?
感谢
答案 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
我将假设第一种技术。
"$@" 2>&1 |
sed '/^In file /,/^ *^/d' >&2
第一行使用命令行中指定的参数运行gcc
(或由参数指定的任何命令;它不必是gcc
)。它将标准输出和标准错误重定向到管道(我将回到此处),这将转到sed
。
sed
行在行的开头查找模式In file
,并从那里删除直到在可选空格后以插入符号开头的第一行。重定向将它传递的信息发送到标准错误。
脚本有两个主要缺陷:
gcc
对标准输出的写入不多。)sed
脚本。你可以处理标准输出与标准错误问题,但它有点令人兴奋(也许是“精神膨胀”)。
(
"$@" 2>&1 1>&3 |
sed '/^In file /,/^ *^/d' >&2
) 3>&1
子shell ( ... ) 3>&1
将写入文件描述符3的数据发送到标准输出。
子shell 2>&1 1>&3 |
内部安排:
sed
命令因此从gcc
获取标准错误输出作为其标准输入,对其进行过滤,>&2
将其标准输出发送到标准错误。
最终结果是标准错误被过滤而标准输出则没有。但是,请注意,由于缓冲的进行,您最终可能会对两个流的输出进行不同的交错。
另一个问题:退出状态。写入的脚本的退出状态是sed
命令的退出状态,在大多数情况下该命令为0。如果我们需要从gcc
转发退出状态,我认为我们必须使用Bash set -o pipefail
。或者你可以戳PIPESTATUS
数组; exit ${PIPESTATUS[0]}
应退出时使用gcc
退出的相同退出状态。
系统正在运行带有GCC 4.9.2的Ubuntu 14.04 LTS衍生产品。
b.c
(我在其他程序上用尽了x.c
,y.c
,z.c
和a.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>