14

Estoy usando la variante boost :: y tengo problemas para compilar en modo de lanzamiento. Estoy trabajando en VC2010 con nivel de advertencia 4 y advertencias como errores. El código siguiente compila bien en el modo de depuración, pero en el modo de lanzamiento recibo un montón de advertencias C4702 del "Código inalcanzable" emitidas en el tiempo de enlace (presumiblemente recibo advertencias del compilador porque hay generación de código de tiempo de enlace cuando las optimizaciones están habilitadas).¿Hay alguna solución para esta advertencia de tiempo de enlace C4702?

¿Alguien ha desactivado con éxito estas advertencias en esta situación? Preferiría mantener el alto nivel de advertencia y las advertencias como errores si es posible.

#pragma warning(disable:4702) 

... parece que no funciona aquí. Aquí hay un código de ejemplo:

#include <boost/variant.hpp> 

struct null{}; 
typedef boost::variant< null, double > variant_t; 

class addition_visitor 
: public boost::static_visitor<variant_t> 
{ 
public: 
    template< typename T, typename U > 
    variant_t operator()(const T&, const U&) const 
    { 
     throw("Bad types"); 
    } 

    variant_t operator()(const double& left, const double& right) const 
    { 
     return variant_t(left * right); 
    } 
}; 

int main(int /*argc*/, char** /*argv*/) 
{ 
    variant_t a(3.0), b(2.0); 
    variant_t c = boost::apply_visitor(addition_visitor(), a, b); 
    return 0; 
} 

El aviso se activa por el operador de plantilla(), que estoy usando para atrapar los intentos de aplicar el visitante a malos tipos de variantes.

+5

Pulgares arriba para el nivel de advertencia 4 + advertencia como errores! –

+0

¿Usted ha intentado poner el pragma en la parte superior del archivo, antes de que la incluye? Y @Matthieu, definitivamente, elimina los errores antes de que aparezcan. – ssube

+1

He intentado poner el pragma en la parte superior del archivo, alrededor de la definición de la clase, alrededor de la llamada a apply_visitor y en la parte superior de stdafx.h. Ninguno de estos parece trabajo, desafortunadamente. – RobH

Respuesta

1

Después de un lugar de almuerzo y un paseo, tengo una solución insatisfactoria pero que funciona bien. En lugar de devolver una variante de mi visitante y tirar en caso de error, vuelvo un éxito booleano y almacenar el resultado, por lo tanto:

#include <boost/variant.hpp> 

struct null{}; 
typedef boost::variant< null, double > variant_t; 

class addition_visitor 
: public boost::static_visitor<bool> 
{ 
public: 
    template< typename T, typename U > 
    bool operator()(const T&, const U&) 
    { 
     //throw("Bad types"); 
     return false; 
    } 

    bool operator()(const double& left, const double& right) 
    { 
     result = variant_t(left * right); 
     return true; 
    } 

    variant_t result; 
}; 

int main(int /*argc*/, char** /*argv*/) 
{ 
    variant_t a(3.0), b(2.0); 
    addition_visitor v; 
    if(!boost::apply_visitor(v, a, b)) 
    { 
     throw("Bad types"); 
    } 

    variant_t c = v.result; 
    return 0; 
} 
1

Por qué proporcionar un cuerpo para el operador de plantilla en absoluto?

No tengo Boost a mano aquí, así que no puedo verificarlo, pero el hecho de que el operador con plantilla tenga un cuerpo probablemente signifique que todas y cada una de las llamadas, independientemente del tipo, compilarán bien, luego lanzarán un error en el tiempo de ejecución.

Deje fuera el cuerpo del operador de plantilla, y simplemente se negará a vincular cuando se utilice con cualquier otro tipo que no sea el doble.

+0

El problema es que el tipo de una variante se determina en tiempo de ejecución. En este caso, la variante tiene un valor de un flujo de datos de mercado, y la selección de valores (y, por lo tanto, sus tipos) es configurable. Esta clase de visitantes podría aplicarse a variantes que contengan un nulo y un doble, por ejemplo, y necesito atrapar eso. El compilador espera que exista un operador válido() para cada par de tipos en la lista de argumentos de la plantilla de variantes; Si declaro el método no doble pero no proporciono una implementación, recibo un error de vinculador externo "no resuelto". – RobH

1

El #pragma no funciona porque este es un tiempo de enlace no una advertencia de tiempo de compilación.

Puede suprimir la advertencia en el modo de lanzamiento. Creo/ignoro: xxxx en la línea de comando del enlazador hará el truco.

+1

Desafortunadamente, la opción de ignorar errores del enlazador se ha eliminado de VC2010. Además, esto es en realidad una advertencia del compilador, generada (reconozco) por la generación de código de tiempo de enlace. – RobH

0

Si declaro el método no doble, pero no proporcionan una implementación entonces aparece un error "sin resolver externo" enlazador .

Intente agregar inline especificador en la definición del operador de la plantilla. Entonces MSVC no debería necesitar que su cuerpo compile la clase en sí. Por lo tanto, en lugar de unresolved external, obtendrá errores de tiempo de compilación solo cuando su código intente usar esta plantilla. Según entiendo, esto es exactamente lo que quieres.

+0

Es posible que haya sido ligeramente engañado por mi código de ejemplo simplificado. En realidad, no sé los tipos de mis variantes en el momento de la compilación. Contienen precios de un feed en vivo, algunos de los cuales pueden ser dobles, algunos nulos. La comprobación de tipos está en tiempo de ejecución, por lo que en tiempo de compilación necesito tener implementaciones (el impulso :: implementación de variante y, por lo tanto, el compilador requiere) del método de visitante para todas las combinaciones posibles de tipo contenido. – RobH

0

Haga que la plantilla operator()(...) sea privada y no proporcione una implementación. Eso atrapará el uso en tiempo de compilación en lugar de tiempo de enlace.

+0

La comprobación del tipo de variante es en tiempo de ejecución (consulte mis comentarios y respuestas en otro sitio), por lo que no proporcionar una implementación no funciona. – RobH

1

Tuve un problema muy similar en un proyecto Visual Studio 2012 MFC; la misma advertencia provino del <memoria> archivo de encabezado, también durante la versión generación de código de tiempo de enlace.
Lo resolví agregando #pragma warning (disable: 4702) al principio del archivo de encabezado precompilado ("stdafx.h" en mi caso, justo antes de #including archivos de cabecera STL).

Cuestiones relacionadas