C ++嵌套pragma警告push / pop

时间:2015-11-11 19:13:08

标签: c++ visual-studio-2010 windows-7 qt5 pragma

我正在使用VS2010开发Win7,其代码库大量使用Qt 5.1.1框架,我们已将编译警告级别设置为4,以便我们可以捕获尽可能多的问题或我们自己的问题。我们正在使用Qt的免费版本,所以我想也许问题出在哪里,但我们从包含的Qt标题中收到大量警告。

我创建了两个头文件,其中一个包含以下内容:

// header file 1
#pragma warning(push)
#pragma warning(disable: 4091)
#pragma warning(disable: 4127)
#pragma warning(disable: 4231)
#pragma warning(disable: 4244)
#pragma warning(disable: 4251)
#pragma warning(disable: 4481)
#pragma warning(disable: 4512)
#pragma warning(disable: 4718)
#pragma warning(disable: 4800)

和另一个具有以下内容:

// header file 2
#pragma warning(pop)

然后围绕代码中的每个Qt头文件或Qt头文件组,我先通过包含头文件1,然后在最后一个Qt头之后我通过包含头文件2结束它。在解决方案的一个小项目中非常好,但对于其中一个大型项目,我仍然会收到很多警告,因为我在头文件1中禁用了代码。

我怀疑并在整个Qt源代码树中做了一个grep,发现有一些标题本身会用pragma警告push / pops。其中一些在代码中间执行此操作,我开始怀疑我的推送是否被他们的pop关闭。

我的问题是,是否可以嵌套#pragma warning(push)指令,就像#ifdef一样?换句话说,就像我能做的那样:

#ifdef DEF1
#ifdef DEF2
<dosomething>
#endif // for DEF2
#endif // for DEF1

是否可以执行以下操作:

// outer layer - my cpp file about to include a Qt header
#pragma warning(push)
#pragma warning(disable: 4091)

// inner layer - included Qt header file pushes and pops and then continues with more code
#pragma warning(push)
#pragma warning(disable: 2403)
<some code that actually uses this stuff>
#pragma warning(pop)

// back to outer layer - my file after the Qt header include
#pragma warning(pop)

或者第一个pop实际上是否同时弹出?我本以为它会嵌套,因为它应该被推到一个堆栈上,但不能找出我仍然看到这些Qt警告的另一个原因。 Qt警告本身正在引用Qt文件,如下所示:

6>c:\qt\qt5.1.1\5.1.1\msvc2010\include\qtcore\qhash.h(72): warning C4127: conditional expression is constant

有关于此的任何想法吗?我已经四处寻找嵌套的pragma警告push / pop,但看不到有人在谈论它,并且下面的警告MSDN页面没有说什么:

https://msdn.microsoft.com/en-us/library/2c8f766e.aspx

非常重要的是要清理它,因为真正的目标是开始处理由于Qt警告泛滥而被忽视的内部警告。

1 个答案:

答案 0 :(得分:0)

使用简单的MCVE:

void test()
{
#pragma warning( push )
#pragma warning( disable : 4305 ) // 'initializing' : truncation from 'double' to 'float'

#pragma warning( push )
#pragma warning( disable : 4244 ) // conversion from 'double' to 'float', possible loss of data
    {
        float f;
        double d = 21.0;
        f = d;  // warning C4244 : '=' : conversion from 'double' to 'float', possible loss of data
    }
#pragma warning( pop )

    {
        float ff = 1.02;  // warning C4305: 'initializing' : truncation from 'double' to 'float'
    }
#pragma warning( pop )

}

并使用Visual Studio 2013编译(我没有检查任何其他内容)导致零警告。这表明(至少天真地)嵌套的pop / push按预期工作。根据外部库,如果使用禁用/默认对(而不是推/弹对),它们实际上可能会启用禁用警告警告:

void test()
{
#pragma warning( push )
#pragma warning( disable : 4305 ) // 'initializing' : truncation from 'double' to 'float'

#pragma warning( disable : 4244 ) // conversion from 'double' to 'float', possible loss of data
#pragma warning( disable : 4305 ) // 'initializing' : truncation from 'double' to 'float'
    {
        float f;
        double d = 21.0;
        f = d;  // warning C4244 : '=' : conversion from 'double' to 'float', possible loss of data
        f = 1.02;  // warning C4305: 'initializing' : truncation from 'double' to 'float'
    }
#pragma warning( default : 4244 ) // conversion from 'double' to 'float', possible loss of data
#pragma warning( default : 4305 ) // 'initializing' : truncation from 'double' to 'float'

    {
        // In this case, the following line results in a warning,
        // despite the #pragma warning( disable : 4305 ) line above
        float ff = 1.02;  // warning C4305: 'initializing' : truncation from 'double' to 'float'
    }
#pragma warning( pop )

}

在这种情况下,我们会在float ff = 1.02;行收到警告,尽管顶部有#pragma warning( disable : 4305 )行。你可以做些什么来关闭所有编译器警告(以便默认关闭)将替换你的

#pragma warning( push )
#pragma warning( disable : 123456789 )
// included external code you don't want to hear about
#pragma warning( pop )

#pragma warning( push, 0 )
// included external code you don't want to hear about
#pragma warning( pop )

将导致没有编译器警告(不包括链接器警告)。