c++ boost g++ boost-optional

c++ - Cómo moverse por GCC ''*((void*) & b+4)'' se puede utilizar sin inicializar en esta función de advertencia mientras se usa boost:: optional



g++ boost-optional (4)

Hay dos niveles de análisis no inicializado en gcc:

  • -Wuninitialized : variables de indicadores que sin duda se utilizan sin inicializar
  • -Wmaybe-uninitialized : variables de indicadores que se utilizan potencialmente sin inicializar

En gcc (*), -Wall enciende ambos niveles a pesar de que este último tiene advertencias espurias porque el análisis es imperfecto. Las advertencias espurias son una plaga, por lo que la forma más sencilla de evitarlas es pasar -Wno-maybe-uninitialized -Wall (después de -Wall ).

Si todavía quiere las advertencias, pero no las tiene causa de error de compilación (a través de -Werror ) puede enumerarlas en blanco usando -Wno-error=maybe-uninitialized .

(*) Clang no se activa -Wmaybe-uninitialized por defecto precisamente porque es muy impreciso y tiene un buen número de falsos positivos; Ojalá gcc siguiera esta directriz también.

Tengo un código similar al siguiente:

#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; }

Al compilar con GCC 4.7.2 con Boost 1.53, use el siguiente comando:

g ++ -c -O2 -Wall -DNDEBUG

Se emite la siguiente advertencia:

13: 3: advertencia: '' ((void ) & b +4)'' puede usarse sin inicializar en esta función [-Wmaybe-uninitized]

Aparentemente, el problema de raíz está en GCC. Ver GCC Bugzilla ¿Alguien sabe una solución?


He encontrado que cambiar la construcción de b en el siguiente código (efectivamente igual):

auto b = boost::make_optional(false,0);

elimina la advertencia. Sin embargo, el siguiente código (que también es efectivamente igual):

boost::optional<int> b(false,0);

no elimina la advertencia. Todavía es un poco insatisfactorio ...


Tuve el mismo problema con este fragmento de código:

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(); } }

No pude deshacerme de la advertencia con la respuesta de Paul Omta, intenté escribir:

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

... sin éxito.

No quería desactivar por completo la advertencia de mi código, así que encontré una solución alternativa que recomendaría: desactivar la advertencia localmente:

#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


Tenía un tipo que no se construyó fácilmente, así que no quería ir a la ruta boost :: make_optional. Asignar una variable automática usando el retorno de una función resolvió este problema para mí. Entonces puedes hacer:

boost::optional<Foo> Default() { return boost::none; } auto var(Default());

Esto también funcionará como una línea lambda, por lo que puedes hacer:

auto var([]()->boost::optional<Foo> { return boost::none; }());