在Visual c++中,可以使用#pragma warning (disable:…)我还发现,在GCC中,您可以覆盖每个文件编译器标志。我怎么能做到这一点为“下一行”,或与推/弹出语义周围的代码区域使用GCC?
当前回答
GCC风格通常不是关闭警告,而是使用标准C结构或__attribute__扩展名来告诉编译器更多关于你的意图的信息。
例如,关于将赋值用作条件的警告通过将赋值放在括号中来抑制,即if ((p=malloc(cnt))而不是if (p=malloc(cnt))。
关于未使用函数参数的警告可以通过一些奇怪的__attribute__我永远都记不住,或者通过自赋值等来抑制。
但一般来说,我更喜欢全局禁用任何警告选项,这些选项会为正确的代码中发生的事情生成警告。
其他回答
GCC风格通常不是关闭警告,而是使用标准C结构或__attribute__扩展名来告诉编译器更多关于你的意图的信息。
例如,关于将赋值用作条件的警告通过将赋值放在括号中来抑制,即if ((p=malloc(cnt))而不是if (p=malloc(cnt))。
关于未使用函数参数的警告可以通过一些奇怪的__attribute__我永远都记不住,或者通过自赋值等来抑制。
但一般来说,我更喜欢全局禁用任何警告选项,这些选项会为正确的代码中发生的事情生成警告。
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 push
#pragma GCC diagnostic ignored "-Wunused-result"
write(foo, bar, baz);
#pragma GCC diagnostic pop
您可以查看GCC诊断指南文档以获得更多详细信息。
我有同样的问题与外部库,如ROS头。我喜欢在CMakeLists.txt中使用以下选项进行更严格的编译:
set(CMAKE_CXX_FLAGS "-std=c++0x -Wall -Wextra -Wstrict-aliasing -pedantic -Werror -Wunreachable-code ${CMAKE_CXX_FLAGS}")
然而,这样做也会在外部包含的库中导致各种迂腐的错误。解决方案是在包含外部库之前禁用所有迂迂的警告,并像这样重新启用它们:
// Save compiler switches
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
// Bad headers with a problem goes here
#include <ros/ros.h>
#include <sensor_msgs/LaserScan.h>
// Restore compiler switches
#pragma GCC diagnostic pop
#pragma GCC diagnostic ignored "-Wformat"
将"-Wformat"替换为警告标志的名称。
AFAIK,这个选项没有办法使用push/pop语义。
推荐文章
- c++中size_t和int的区别是什么?
- 在C和c++中静态变量存储在哪里?
- errno线程安全吗?
- 如何在C程序中获取当前目录?
- 互斥实例/教程?
- 如何添加一个'或'条件在#ifdef
- extern关键字对C函数的影响
- 如果使用if-return-return或if-else-return?
- 转换Python程序到C/ c++代码?
- 为什么程序不是经常用汇编编写的?
- 有没有替换Windows (Visual C)的unistd.h ?
- 属性getter和setter
- 使用gcc命令行从.c文件构建.so文件
- C多行宏:do/while(0) vs作用域块
- time_t最终的类型定义是什么?