在Visual c++中,可以使用#pragma warning (disable:…)我还发现,在GCC中,您可以覆盖每个文件编译器标志。我怎么能做到这一点为“下一行”,或与推/弹出语义周围的代码区域使用GCC?
当前回答
这是一个暂时禁用警告的例子:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
write(foo, bar, baz);
#pragma GCC diagnostic pop
您可以查看GCC诊断指南文档以获得更多详细信息。
其他回答
GCC风格通常不是关闭警告,而是使用标准C结构或__attribute__扩展名来告诉编译器更多关于你的意图的信息。
例如,关于将赋值用作条件的警告通过将赋值放在括号中来抑制,即if ((p=malloc(cnt))而不是if (p=malloc(cnt))。
关于未使用函数参数的警告可以通过一些奇怪的__attribute__我永远都记不住,或者通过自赋值等来抑制。
但一般来说,我更喜欢全局禁用任何警告选项,这些选项会为正确的代码中发生的事情生成警告。
这是一个暂时禁用警告的例子:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
write(foo, bar, baz);
#pragma GCC diagnostic pop
您可以查看GCC诊断指南文档以获得更多详细信息。
TL;DR:如果它工作,避免,或使用像_Noreturn, [[nodiscard]], __attribute__这样的说明符,否则_Pragma。
这是我博客文章的一个简短版本 GCC和Clang中的抑制警告。
考虑下面的Makefile,
CPPFLAGS:=-std=c11 -W -Wall -pedantic -Werror
.PHONY: all
all: puts
构建下面的put .c源代码:
#include <stdio.h>
int main(int argc, const char *argv[])
{
while (*++argv)
puts(*argv);
return 0;
}
它将无法编译,因为argc未使用,并且设置是核心的(-W -Wall -pedantic -Werror)。
你可以做以下五件事:
如果可能的话,改进源代码 使用一个属性,比如[[maybe_unused]] 使用声明说明符,如__attribute__ 使用_Pragma 使用# pragma 使用命令行选项。
改进源代码
第一次尝试应该是检查源代码是否可以改进以消除警告。在这种情况下,我们不想仅仅因为这一点而改变算法,因为argc对于!*argv(最后一个元素后为NULL)是多余的。
使用属性,如[[maybe_unused]]
#include <stdio.h>
int main([[maybe_unused]] int argc, const char *argv[])
{
while (*++argv) puts(*argv);
return 0;
}
如果幸运的话,标准为您的情况提供了一个属性,如[[maybe_unused]]。属性是C2x的新特性。到目前为止,C2x定义了四个属性,[[deprecated]]、[[fallthrough]]、[[maybe_unused]]和[[nodiscard]]。
使用声明说明符,如__attribute__
#include <stdio.h>
int main(__attribute__((unused)) int argc, const char *argv[])
{
while (*++argv) puts(*argv);
return 0;
}
如果幸运的话,标准为您的情况提供了一个说明符,如_Noreturn。
__attribute__是GCC专有扩展(Clang和一些其他编译器,如armcc也支持),许多其他编译器无法理解。如果你想要可移植的代码,将__attribute__((未使用))放在宏中。
_Pragma运营商
_Pragma可以作为#pragma的替代。
#include <stdio.h>
_Pragma("GCC diagnostic push")
_Pragma("GCC diagnostic ignored \"-Wunused-parameter\"")
int main(int argc, const char *argv[])
{
while (*++argv)
puts(*argv);
return 0;
}
_Pragma("GCC diagnostic pop")
_Pragma操作符的主要优点是你可以把它放在宏中,而#pragma指令是不可能做到的。
缺点:它几乎是一个战术核武器,因为它是基于行而不是基于声明的。
_Pragma操作符是在C99中引入的。
# pragma directive。
我们可以更改源代码来抑制对代码区域(通常是整个函数)的警告:
#include <stdio.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
int main(int argc, const char *argv[])
{
while (*++argc) puts(*argv);
return 0;
}
#pragma GCC diagnostic pop
缺点:它几乎是一个战术核武器,因为它是基于行而不是基于声明的。
注意,Clang中也存在类似的语法。
对单个文件取消命令行上的警告
我们可以在Makefile中添加下面这行代码来抑制针对看跌期权的警告:
CPPFLAGS:=-std=c11 -W -Wall -pedantic -Werror
.PHONY: all
all: puts
puts.o: CPPFLAGS+=-Wno-unused-parameter
在你的特定情况下,这可能不是你想要的,但它可能会帮助其他有类似情况的读者。
#pragma GCC diagnostic ignored "-Wformat"
将"-Wformat"替换为警告标志的名称。
AFAIK,这个选项没有办法使用push/pop语义。
在IAR中有一种方法可以做到这一点。试试这个:
#pragma diag_suppress=Pe177
void foo1(void)
{
/* The following line of code would normally provoke diagnostic
message #177-D: variable "x" was declared but never referenced.
Instead, we have suppressed this warning throughout the entire
scope of foo1().
*/
int x;
}
#pragma diag_default=Pe177
参考官方文件。
推荐文章
- C中的>>>=运算符是什么?
- GCC转储预处理器定义
- 如何在C中实现函数重载?
- 如何在Mac OS X 10.8 / Xcode 4.4上使用/安装gcc
- pty和tty是什么意思?
- 结构填充物和填料
- 如何禁用几行代码的GCC警告
- bool是否是原生C类型?
- .c vs .cc vs .cpp vs .hpp vs .h vs .cxx
- 实现基于整数的幂函数pow(int, int)的最有效方法
- 如何正确使用extern关键字在C
- 为什么gets函数如此危险以至于不应该使用它?
- 为什么NaN - NaN == 0.0与英特尔c++编译器?
- 空终止字符串的基本原理是什么?
- C如何计算sin()和其他数学函数?