在使用boost :: optional时,如何绕过GCC'*((void*)&b +4)'可以在此函数警告中未初始化

Pau*_*mta 28 c++ boost g++ boost-optional

我有类似以下代码:

#include <boost/optional.hpp>

::boost::optional<int> getitem();

int go(int nr)
{
  boost::optional<int> a = getitem();
  boost::optional<int> b;

  if (nr > 0)
    b = nr;

  if (a != b)
    return 1;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用Boost 1.53使用GCC 4.7.2进行编译时,使用以下命令:

g ++ -c -O2 -Wall -DNDEBUG

发出以下警告:

13:3:警告:' ((void)&b +4)'可以在此函数中未初始化使用[-Wyybe-uninitialized]

显然,根本问题在于海湾合作委员会.请参阅GCC Bugzilla 有没有人知道解决方法?

Mat*_* M. 29

gcc中有两个级别的未初始化分析:

  • -Wuninitialized:标记肯定使用未初始化的变量
  • -Wmaybe-uninitialized:标记可能未初始化的变量

在gcc(*)中,-Wall即使后者具有虚假警告,也会打开这两个级别,因为分析不完善.虚假警告是一种瘟疫,因此避免它们的最简单方法是通过-Wno-maybe-uninitialized(之后-Wall).

如果您仍然需要警告,但没有它们导致构建失败(通过-Werror),您可以使用白名单-Wno-error=maybe-uninitialized.

(*)Clang -Wmaybe-uninitialized默认情况下不会激活,因为它非常不精确并且具有大量的误报; 我希望gcc也遵循这个准则.


Pau*_*mta 14

我发现将b的结构改为以下(实际上相等)代码:

auto b = boost::make_optional(false,0);
Run Code Online (Sandbox Code Playgroud)

消除了警告.但是,以下代码(实际上也相等):

boost::optional<int> b(false,0);
Run Code Online (Sandbox Code Playgroud)

不消除警告.它仍然有点令人不满意......


jpo*_*o38 5

这段代码有同样的问题:

void MyClass::func( bool repaint, bool cond )
{
    boost::optional<int> old = m_sizeLimit; // m_sizeLimit is a boost::optional<int> class attribute

    if ( cond )
        m_sizeLimit = 60;
    else
        m_sizeLimit.reset();

    if ( repaint )
    {
        if ( old != m_sizeLimit ) // warning here
            doSomething();
    }
}
Run Code Online (Sandbox Code Playgroud)

无法用Paul Omta的答案摆脱警告,试图写道:

boost::optional<int> old;
if ( m_sizeLimit )
    old = boost::make_optional<int>(true, m_sizeLimit.value());
else
    old = boost::make_optional<int>(false, 0);
Run Code Online (Sandbox Code Playgroud)

......没有成功.

不想完全禁用我的代码中的警告,所以我找到了一个替代解决方案,我建议:在本地禁用警告:

        #ifdef SDE_MOBILE
        #pragma GCC diagnostic push
        #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
        #endif

        if ( old != m_sizeLimit ) // warning here
            doSomething();

        #ifdef SDE_MOBILE
        #pragma GCC diagnostic pop
        #endif
Run Code Online (Sandbox Code Playgroud)