在Visual c++中,可以使用#pragma warning (disable:…)我还发现,在GCC中,您可以覆盖每个文件编译器标志。我怎么能做到这一点为“下一行”,或与推/弹出语义周围的代码区域使用GCC?


当前回答

Use:

#define DIAG_STR(s) #s
#define DIAG_JOINSTR(x,y) DIAG_STR(x ## y)
#ifdef _MSC_VER
#define DIAG_DO_PRAGMA(x) __pragma (#x)
#define DIAG_PRAGMA(compiler,x) DIAG_DO_PRAGMA(warning(x))
#else
#define DIAG_DO_PRAGMA(x) _Pragma (#x)
#define DIAG_PRAGMA(compiler,x) DIAG_DO_PRAGMA(compiler diagnostic x)
#endif
#if defined(__clang__)
# define DISABLE_WARNING(gcc_unused,clang_option,msvc_unused) DIAG_PRAGMA(clang,push) DIAG_PRAGMA(clang,ignored DIAG_JOINSTR(-W,clang_option))
# define ENABLE_WARNING(gcc_unused,clang_option,msvc_unused) DIAG_PRAGMA(clang,pop)
#elif defined(_MSC_VER)
# define DISABLE_WARNING(gcc_unused,clang_unused,msvc_errorcode) DIAG_PRAGMA(msvc,push) DIAG_DO_PRAGMA(warning(disable:##msvc_errorcode))
# define ENABLE_WARNING(gcc_unused,clang_unused,msvc_errorcode) DIAG_PRAGMA(msvc,pop)
#elif defined(__GNUC__)
#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
# define DISABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,push) DIAG_PRAGMA(GCC,ignored DIAG_JOINSTR(-W,gcc_option))
# define ENABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,pop)
#else
# define DISABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,ignored DIAG_JOINSTR(-W,gcc_option))
# define ENABLE_WARNING(gcc_option,clang_option,msvc_unused) DIAG_PRAGMA(GCC,warning DIAG_JOINSTR(-W,gcc_option))
#endif
#endif

这应该做的伎俩GCC, Clang和MSVC。

它可以用例如:

DISABLE_WARNING(unused-variable,unused-variable,42)
[.... some code with warnings in here ....]
ENABLE_WARNING(unused-variable,unused-variable,42)

参见7 Pragmas,通过Pragmas和Pragma指令控制诊断,以及__pragma和_Pragma关键字了解更多细节。

你至少需要4.02版本才能使用GCC的这些代码,我不确定MSVC和Clang的版本。

看起来GCC的push pop pragma处理有点坏。如果再次启用警告,仍然会得到DISABLE_WARNING/ENABLE_WARNING块内部的警告。对于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语义。

GCC风格通常不是关闭警告,而是使用标准C结构或__attribute__扩展名来告诉编译器更多关于你的意图的信息。

例如,关于将赋值用作条件的警告通过将赋值放在括号中来抑制,即if ((p=malloc(cnt))而不是if (p=malloc(cnt))。

关于未使用函数参数的警告可以通过一些奇怪的__attribute__我永远都记不住,或者通过自赋值等来抑制。

但一般来说,我更喜欢全局禁用任何警告选项,这些选项会为正确的代码中发生的事情生成警告。

这似乎是可以做到的。我无法确定它添加的GCC版本,但它是在2010年6月之前的某个时候。

这里有一个例子:

#pragma GCC diagnostic error "-Wuninitialized"
    foo(a);         /* error is given for this one */

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
    foo(b);         /* no diagnostic for this one */
#pragma GCC diagnostic pop

    foo(c);         /* error is given for this one */
#pragma GCC diagnostic pop 

    foo(d);         /* depends on command line options */

这是一个暂时禁用警告的例子:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
    write(foo, bar, baz);
#pragma GCC diagnostic pop

您可以查看GCC诊断指南文档以获得更多详细信息。